Skip to content

Conversation

@zubron
Copy link
Contributor

@zubron zubron commented Nov 6, 2025

Closes #5251

Change Description

Background

The UI for adding metadata fields allowed empty key-value pairs to be added. This is different from the CLI behaviour which filters them. While we plan to add server-side validation for empty metadata keys in a future update, for now, we want to provide client-side validation to give immediate user feedback and avoid unnecessary API calls that would fail validation.

Bug Fix

Add client-side validation to prevent form submission (commit, merge, import) when metadata keys are empty or whitespace-only.

Fields are marked as invalid when:

  • User blurs an empty key input
  • Form is submitted with empty keys

Invalid fields display "Key is required" error message.

Screenshot 2025-11-18 at 2 23 02 PM Screenshot 2025-11-18 at 2 23 39 PM

Testing Details

Added component tests using React Testing Library to verify validation behaviour.
Also performed manual testing to verify behaviour when interacting with many fields.

@zubron zubron force-pushed the fix/empty-metadata-keys-are-allowed-5251 branch 2 times, most recently from 8047280 to 5acff90 Compare November 17, 2025 21:19
@zubron zubron added area/UI Improvements or additions to UI include-changelog PR description should be included in next release changelog labels Nov 17, 2025
@zubron zubron changed the title Filter empty key-value metadata pairs in UI Prevent submission of empty metadata keys Nov 17, 2025
@zubron zubron force-pushed the fix/empty-metadata-keys-are-allowed-5251 branch 4 times, most recently from 33df7ec to 19508be Compare November 18, 2025 19:20
@zubron zubron changed the title Prevent submission of empty metadata keys Enforce non-empty metadata keys in forms Nov 18, 2025
@zubron zubron marked this pull request as ready for review November 18, 2025 19:31
Add client-side validation to prevent form submission (commit, merge,
import) when metadata keys are empty or whitespace-only.

Fields are marked invalid when:
- User blurs an empty key input
- Form is submitted with empty keys

Invalid fields display "Key is required" error message.

Added component tests using React Testing Library to verify validation
behavior.

Closes #5251
@zubron zubron force-pushed the fix/empty-metadata-keys-are-allowed-5251 branch from 19508be to 47c9992 Compare November 18, 2025 19:34
@zubron zubron requested review from itaigilo and nopcoder November 20, 2025 14:52
@zubron
Copy link
Contributor Author

zubron commented Nov 20, 2025

@nopcoder - I'm tagging you on this to see if this is the right approach for the UI to take with empty metadata keys. I checked the UI of S3. When using the S3 API directly, they don't error on empty metadata keys, but they do show an error on the UI.

Screenshot 2025-11-20 at 10 13 06 AM

@nopcoder
Copy link
Contributor

@nopcoder - I'm tagging you on this to see if this is the right approach for the UI to take with empty metadata keys. I checked the UI of S3. When using the S3 API directly, they don't error on empty metadata keys, but they do show an error on the UI.

Screenshot 2025-11-20 at 10 13 06 AM

@zubron if calling s3 with empty metadata key, do not fail as invalid request - is getting the metadata returns the value? if there is no value or a way to set an empty metadata key object s3, we can make the UI's UX friendly and keep our gateway S3 behaviour the same.

@nopcoder
Copy link
Contributor

@nopcoder - I'm tagging you on this to see if this is the right approach for the UI to take with empty metadata keys. I checked the UI of S3. When using the S3 API directly, they don't error on empty metadata keys, but they do show an error on the UI.
Screenshot 2025-11-20 at 10 13 06 AM

@zubron if calling s3 with empty metadata key, do not fail as invalid request - is getting the metadata returns the value? if there is no value or a way to set an empty metadata key object s3, we can make the UI's UX friendly and keep our gateway S3 behaviour the same.

As there is no way to get metadata with empty key and the API just ignore them if you set an empty key - I think that the UX can block (perform validation) setting this case.

Copy link
Contributor

@itaigilo itaigilo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for handling this @zubron ,
Looking pretty good.

There are still some changes required, mainly about tidying up the code.

if (committing) return;
setShow(false)
setShow(false);
setMetadataFields([]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why setting to []?
It clears the user's work in case of closing and re-opening, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right. This does clear any entries when closing and opening again, and this is modifying the existing behaviour. I think I added this because the commit message is not persisted across the same flow so it seemed to stand out that the metadata persisted. Happy to revert it though!

}

const onSubmit = async () => {
if (!validateMetadataKeys(metadataFields, setMetadataFields)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part repeats itself...

How about extracting metadataFields.forEach(pair => metadata[pair.key] = pair.value) into a function, and validateMetadataKeys() in this extracted function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is needed to add test matchers like toBeInTheDocument() and toHaveValue() to Vitest, and to automatically clean up React components between tests.

/>
{showError && (
<Form.Control.Feedback type="invalid">
Key is required
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make this more generic:
Something like:

const fieldError = getFieldError(f);
...
{fieldError && (<Form.Control.Feedback type="invalid">{fieldError}</Form.Control>)}

* @param {Function} setMetadataFields - Setter function to update metadata fields
* @returns {boolean} True if validation passed (no empty keys), false if validation failed
*/
export const validateMetadataKeys = (metadataFields, setMetadataFields) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like mixing two things here:
I don't expect a validation function to also update the state (in this case, by using setMetadataFields).

I think it's better to split it into hasEmptyKeys() and touchEmptyKeys(),
But maybe there's a nicer solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right, that shouldn't be happening in this function. I've separated this into two pure functions which returns responsibility for updating state back to the parent component, and should also help with the duplication that you mentioned in another comment above.

@zubron
Copy link
Contributor Author

zubron commented Nov 24, 2025

As there is no way to get metadata with empty key and the API just ignore them if you set an empty key - I think that the UX can block (perform validation) setting this case.

Thanks for taking a look at this, @nopcoder. Yes, my understanding is that there is no way to retrieve the metadata with the empty key. When a user tries to retrieve the object, the response will include the x-amz-missing-meta header with how many entries can't be returned via HTTP headers. I believe this header was originally used for the SOAP API but that has since been deprecated (EOL October 2025), and is not recommended for use.

https://gist.github.com/zubron/783dc8ccdaba2108a5453086031e8785#2-empty-keys

@nopcoder
Copy link
Contributor

nopcoder commented Nov 24, 2025

As there is no way to get metadata with empty key and the API just ignore them if you set an empty key - I think that the UX can block (perform validation) setting this case.

Thanks for taking a look at this, @nopcoder. Yes, my understanding is that there is no way to retrieve the metadata with the empty key. When a user tries to retrieve the object, the response will include the x-amz-missing-meta header with how many entries can't be returned via HTTP headers. I believe this header was originally used for the SOAP API but that has since been deprecated (EOL October 2025), and is not recommended for use.

https://gist.github.com/zubron/783dc8ccdaba2108a5453086031e8785#2-empty-keys

#zubron, So the only issue we still need to fix is the backend storing an empty key's value, right? (not as part of this PR)

@zubron
Copy link
Contributor Author

zubron commented Nov 24, 2025

#zubron, So the only issue we still need to fix is the backend storing an empty key's value, right? (not as part of this PR)

Yep, I'll open another issue for that 👍

Validation functions do not modify state, instead makes it the parent
component's responsibility.
@zubron zubron force-pushed the fix/empty-metadata-keys-are-allowed-5251 branch from 01834e0 to 81ceb24 Compare November 26, 2025 21:23
@zubron zubron requested a review from itaigilo November 26, 2025 21:23
Copy link
Contributor

@itaigilo itaigilo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/UI Improvements or additions to UI include-changelog PR description should be included in next release changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UI: On commit - empty metadata keys are allowed

3 participants