Skip to content

fix: validate custom property name charset#27808

Open
sonika-shah wants to merge 26 commits intomainfrom
fix/custom-property-name-charset-validation
Open

fix: validate custom property name charset#27808
sonika-shah wants to merge 26 commits intomainfrom
fix/custom-property-name-charset-validation

Conversation

@sonika-shah
Copy link
Copy Markdown
Collaborator

@sonika-shah sonika-shah commented Apr 29, 2026

Fixes #27699

Summary

Tighten custom property name validation to block characters that empirically break downstream parsers. Adds a new customPropertyName schema definition, defense-in-depth Java validation in TypeRepository, a schema-vs-Java consistency test that prevents drift between the two, and integration tests covering allowed/blocked charsets, leading-character rules, length, and unbalanced brackets.

Why

Custom property names previously inherited the very permissive entityName pattern (^((?!::).)*$), which only blocks ::. A matrix run on 1.13 across 24 special chars × 17 property types × 4 operations identified five characters that break specific operations regardless of property type:

char breaks how
" CREATE HTTP 500 from PUT /metadata/types/{id}
: CSV import exporter writes key:value;key:value; importer splits at first :, treats prefix as the field name (Unknown custom field: <prefix>)
^ Search when the name is in searchSettings.searchFields, OpenSearch reads ^ as the boost separator in the field^boost grammar (x_content_parse_exception [bool] failed to parse field [should])
$ CSV import Java Matcher.replaceAll interprets $<letter> as a regex backreference (Illegal group reference) when the value contains certain characters
\ CSV import escape inconsistency in CSV serialization for entityReference / entityReferenceList types (export emits double-backslash, import un-escapes to single, key lookup fails)

All other tested characters (alphanumeric, _, -, ., /, &, %, #, @, !, ,, ;, =, |, ', +, ?, *, ~, `, space, (, ), <, >, [, ], {, }) round-trip cleanly across CREATE / PATCH / CSV (real, non-dry-run) / Search across all 17 property types, including multi-property CSV roundtrips that exercise the ; and , CSV-quoting layer.

Note: subsequent live testing on the actual Explore searchFields path tightened the blocklist further. &, <, > are blocked because DOMPurify on the UI auto-encodes them to HTML entities, producing inconsistent stored values. * is blocked because it triggers ES field-path wildcard expansion in extension.<propertyName>^boost lookups — the literal field never satisfies its own wildcard pattern, so Explore search silently drops it. See the "Final charsets" section below for the authoritative list.

Final charsets

  • Allow: A-Z a-z 0-9 _ - . / % # @ ! , ; = | ' + ? ~ space ( ) [ ] { }`
  • Block: " * & < > : ^ $ \

The initial CSV/Create/Search matrix in the "Why" section above identified five chars that broke specific operations and recommended allowing the rest. After it was opened, additional empirical testing on a running OpenSearch instance with extension.<propertyName>^boost configured in searchSettings.searchFields (the actual Explore search path) revealed that * triggers ES field-path wildcard expansion (the literal-* field never satisfies its own pattern) and silently drops the field from the query. &, <, > were tightened separately because DOMPurify on the UI auto-encodes them to HTML entities, producing inconsistent stored values. So the final blocklist is ", :, ^, $, \ (the original five) plus * (search bypass) plus &, <, > (UI sanitization).

Changes

  • openmetadata-spec/.../type/basic.json — adds customPropertyName definition with regex ^[A-Za-z0-9][A-Za-z0-9 _\-.,;/&%#@!'(){}\[\]<>|=+?*~]*$`, max length 256.
  • openmetadata-spec/.../type/customProperty.jsonname now $refs customPropertyName instead of entityName.
  • openmetadata-service/.../jdbi3/TypeRepository.java — adds validateCustomPropertyName(String) called from validateProperty(CustomProperty) so the API returns 400 with a clear, human-readable error message even if schema validation is bypassed (e.g. internal callers that don't go through the @Valid-protected resource layer).
  • openmetadata-service/.../jdbi3/TypeRepositoryTest.java (new) — schema-vs-Java consistency tests that load basic.json at runtime and assert the pattern and maxLength match the TypeRepository constants. Drift in either direction fails CI with a message naming both files.

Why two layers + a sync test (instead of one)

Each layer earns its keep:

  • JSON Schema is the single source of truth visible to clients, generated SDKs, and the request-time @Valid Bean Validation flow.
  • Java validator gives a much better error message than the default @Pattern violation (which dumps the raw regex), and runs even on code paths that build CustomProperty programmatically without crossing the HTTP boundary.
  • Consistency test ensures the two cannot drift — touching one without the other fails CI immediately.

Backwards compatibility

Name validation is scoped to newly added custom properties (the added list computed by TypeUpdater.updateCustomProperties() via recordListChange against the entity's stored state).

  • A custom property whose name contains a now-blocked character but already exists in storage continues to read normally, AND its description / displayName / config can still be updated without re-validating its name. Same name + same propertyType means it's not in added, so the regex is never re-checked.
  • Any new property added to a Type — through PUT /types/{id} (addCustomProperty), PATCH /types/{id} (JsonPatch), or any internal call into repository.createOrUpdate — is validated against the schema-derived @Pattern/@Size/@NotNull annotations on the generated CustomProperty.java and rejected with HTTP 400 if its name violates the rule.

This was a deliberate scope narrowing in response to review feedback (#27808 review note): an earlier iteration validated every property in customProperties[] on every Type write, which meant an upgraded instance with a single legacy bad-named property would have any subsequent PUT/PATCH on that Type rejected — even when the write merely updated the description of a different, valid property. Restricting validation to new additions preserves write-time backwards compatibility while still preventing any newly introduced bad name from reaching the database via any write path.

Test plan

Unit tests in openmetadata-service (TypeRepositoryTest)

  • customPropertyNamePatternMatchesSchema — schema regex matches Java Pattern
  • customPropertyNameMaxLengthMatchesSchema — schema maxLength matches Java constant
  • customPropertyNameDefinitionIsRequiredString — definition shape sanity check

Integration tests in openmetadata-integration-tests (TypeResourceIT)

  • test_customPropertyNameAllowedCharacters_succeeds — 31 names spanning every safe character (including +, ?, *, ~, `)
  • test_customPropertyNameDisallowedCharacters_fails — verifies ", :, ^, $, \ are rejected
  • test_customPropertyNameMustStartWithAlphanumeric_fails — leading char rule for _, -, ., , (, <
  • test_customPropertyNameTooLong_fails — > 256 character names rejected
  • test_customPropertyNameUnbalancedBrackets_succeeds(, ), <, >, [, ], {, } accepted unbalanced (no closure required)
  • Existing tests untouched

🤖 Generated with Claude Code


Summary by Gitar

  • Integration testing:
    • Added field-specific fetching to getTypeById in TypeResourceIT to ensure customProperties are populated during validation checks.

This will update automatically on new commits.

Copilot AI review requested due to automatic review settings April 29, 2026 07:02
@github-actions github-actions Bot added backend safe to test Add this label to run secure Github workflows on PRs labels Apr 29, 2026
@github-actions
Copy link
Copy Markdown
Contributor

✅ TypeScript Types Auto-Updated

The generated TypeScript types have been automatically updated based on JSON schema changes in this PR.

@github-actions github-actions Bot requested a review from a team as a code owner April 29, 2026 07:07
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR tightens custom property name validation to prevent a small set of characters that break downstream parsers, by enforcing a stricter JSON Schema pattern plus server-side validation and integration tests.

Changes:

  • Added a customPropertyName definition in basic.json with a restricted character set and max length.
  • Updated customProperty.json to validate name against customPropertyName instead of entityName.
  • Added Java-side validation in TypeRepository and integration tests in TypeResourceIT for allowed/disallowed names, leading character, and length rules.

Reviewed changes

Copilot reviewed 4 out of 6 changed files in this pull request and generated 1 comment.

File Description
openmetadata-spec/src/main/resources/json/schema/type/customProperty.json Switches name validation to the new customPropertyName definition and updates the field description to document the new rules.
openmetadata-spec/src/main/resources/json/schema/type/basic.json Introduces the reusable customPropertyName schema definition (pattern + length).
openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TypeRepository.java Adds defense-in-depth validation for custom property names during add/update operations.
openmetadata-integration-tests/src/test/java/org/openmetadata/it/tests/TypeResourceIT.java Adds integration coverage for allowed/disallowed character sets, leading character rules, and max length.

@github-actions
Copy link
Copy Markdown
Contributor

The Java checkstyle failed.

Please run mvn spotless:apply in the root of your repository and commit the changes to this PR.
You can also use pre-commit to automate the Java code formatting.

You can install the pre-commit hooks with make install_test precommit_install.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 62%
62.45% (62923/100756) 42.77% (33911/79285) 45.77% (10035/21924)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

🔴 Playwright Results — 1 failure(s), 17 flaky

✅ 3987 passed · ❌ 1 failed · 🟡 17 flaky · ⏭️ 93 skipped

Shard Passed Failed Flaky Skipped
✅ Shard 1 299 0 0 4
🟡 Shard 2 748 0 6 8
🔴 Shard 3 781 1 2 14
🟡 Shard 4 743 0 1 18
🟡 Shard 5 685 0 2 41
🟡 Shard 6 731 0 6 8

Genuine Failures (failed on all attempts)

Pages/CustomProperties.spec.ts › table-cp shows row count, scrollable container, no expand toggle (shard 3)
�[31mTest timeout of 180000ms exceeded.�[39m
🟡 17 flaky test(s) (passed on retry)
  • Features/ActivityAPI.spec.ts › Activity event is created when description is updated (shard 2, 1 retry)
  • Features/ActivityAPI.spec.ts › Activity event shows the actor who made the change (shard 2, 1 retry)
  • Features/DataProductRename.spec.ts › should update only display name without changing the actual name (shard 2, 1 retry)
  • Features/Glossary/GlossaryHierarchy.spec.ts › should cancel move operation (shard 2, 1 retry)
  • Features/Glossary/GlossaryWorkflow.spec.ts › should display correct status badge color and icon (shard 2, 2 retries)
  • Features/Glossary/LargeGlossaryPerformance.spec.ts › should search and filter glossary terms (shard 2, 1 retry)
  • Features/RTL.spec.ts › Verify Following widget functionality (shard 3, 1 retry)
  • Features/UserProfileOnlineStatus.spec.ts › Should show online status badge on user profile for active users (shard 3, 1 retry)
  • Pages/CustomProperties.spec.ts › Entity Reference List (shard 4, 1 retry)
  • Pages/Entity.spec.ts › User as Owner with unsorted list (shard 5, 1 retry)
  • Pages/Entity.spec.ts › Announcement create, edit & delete (shard 5, 1 retry)
  • Pages/Glossary.spec.ts › Column selection and visibility for Glossary Terms table (shard 6, 1 retry)
  • Pages/Lineage/LineageFilters.spec.ts › Verify lineage schema filter selection (shard 6, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab IS visible for supported type: searchIndex (shard 6, 1 retry)
  • Pages/ODCSImportExport.spec.ts › Multi-object ODCS contract - object selector shows all schema objects (shard 6, 1 retry)
  • Pages/ServiceEntity.spec.ts › Tier Add, Update and Remove (shard 6, 1 retry)
  • Pages/Users.spec.ts › Create and Delete user (shard 6, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

Copilot AI review requested due to automatic review settings April 29, 2026 10:23
@github-actions
Copy link
Copy Markdown
Contributor

The Java checkstyle failed.

Please run mvn spotless:apply in the root of your repository and commit the changes to this PR.
You can also use pre-commit to automate the Java code formatting.

You can install the pre-commit hooks with make install_test precommit_install.

@github-actions
Copy link
Copy Markdown
Contributor

✅ TypeScript Types Auto-Updated

The generated TypeScript types have been automatically updated based on JSON schema changes in this PR.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 7 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TypeRepository.java:228

  • validateCustomPropertyName is only invoked from validateProperty(CustomProperty), which is used by the /types/{id} add/update-property endpoint. Other write paths (notably TypeUpdater.updateCustomProperties()storeCustomProperty() during PUT/PATCH of a Type) can still persist custom properties without any name validation, allowing clients to bypass this restriction via JSON Patch/PUT. Consider validating all updated.getCustomProperties() entries (e.g., call validateCustomPropertyName/validateProperty for added items, or enforce it in prepare(Type, boolean) for every custom property) so the rule cannot be bypassed.
  private void validateProperty(CustomProperty customProperty) {
    validateCustomPropertyName(customProperty.getName());
    switch (customProperty.getPropertyType().getName()) {
      case "enum" -> validateEnumConfig(customProperty.getCustomPropertyConfig());
      case "table-cp" -> validateTableTypeConfig(customProperty.getCustomPropertyConfig());
      case "date-cp" -> validateDateFormat(

Comment thread openmetadata-spec/src/main/resources/json/schema/type/customProperty.json Outdated
Comment thread openmetadata-spec/src/main/resources/json/schema/type/basic.json
@github-actions
Copy link
Copy Markdown
Contributor

The Java checkstyle failed.

Please run mvn spotless:apply in the root of your repository and commit the changes to this PR.
You can also use pre-commit to automate the Java code formatting.

You can install the pre-commit hooks with make install_test precommit_install.

Tighten custom property name validation to block characters that break
downstream parsers, with verified empirical reproduction:

- `"` causes HTTP 500 on PUT /metadata/types/{id}
- `:` breaks CSV import — exporter writes `key:value;key:value`, importer
  splits at first colon, treats prefix as the field name
- `^` breaks OpenSearch query when the name is in
  searchSettings.searchFields — Lucene reads `^` as the boost separator
  in `field^boost`
- `$` breaks CSV import via java.util.regex.Matcher.replaceAll which
  interprets `$<letter>` as a backreference

Adds a `customPropertyName` definition in basic.json and switches
customProperty.json to reference it. Adds a defensive regex check in
TypeRepository.validateProperty so the API returns 400 with a clear
error message even if schema validation is bypassed.

Tests cover allowed-charset acceptance, the four blocked characters,
leading-character validation, max-length enforcement, and unbalanced
brackets.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 31 out of 33 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

openmetadata-ui/src/main/resources/ui/src/components/common/SanitizedInput/SanitizedInput.tsx:32

  • shouldSanitize is now part of this component's public API, but handleChange still only depends on onChange. If a caller toggles shouldSanitize without remounting, the callback keeps using the old mode and sanitizes (or skips sanitizing) incorrectly until the component is recreated.
  const handleChange = useCallback(
    (e: ChangeEvent<HTMLInputElement>) => {
      const sanitizedValue = shouldSanitize
        ? getSanitizeContent(e.target.value)
        : e.target.value;
      if (onChange) {
        onChange({ ...e, target: { ...e.target, value: sanitizedValue } });
      }
    },
    [onChange]

Comment thread openmetadata-spec/src/main/resources/json/schema/type/customProperty.json Outdated
Comment thread openmetadata-ui/src/main/resources/ui/src/constants/regex.constants.ts Outdated
Comment thread openmetadata-ui/src/main/resources/ui/playwright/constant/customProperty.ts Outdated
Copilot AI review requested due to automatic review settings May 5, 2026 06:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

sonika-shah and others added 2 commits May 5, 2026 15:24
Schema-side counterpart to the UI changes in the previous two commits:
basic.json#/definitions/customPropertyName now blocks &, <, > alongside the
existing " : ^ $ \\. The DOMPurify pass on the UI sanitizes &, <, > into HTML
entities, which produced inconsistent persisted values; rejecting them at the
schema layer prevents that drift across all write paths.

IT updates:
- Drop &, <, > from the allowed-charset cases (and the "withMatched(pair)And<more>" composite)
- Add &, <, > to the disallowed-charset cases
- Drop "<" leading-character case (now covered as a disallowed character)
- Drop "<" / ">" unbalanced-bracket cases
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

✅ TypeScript Types Auto-Updated

The generated TypeScript types have been automatically updated based on JSON schema changes in this PR.

Bean Validation runs for the dedicated PUT /types/{id} (addOrUpdateProperty)
because the resource declares @Valid CustomProperty, and the createOrUpdate
path can't carry customProperties at all (CreateType schema doesn't include
the field). PATCH /types/{id} accepts an opaque JsonPatch, so @Valid never
reaches into the resulting customProperties[] — a JSON Patch like
[{"op":"add","path":"/customProperties/-","value":{"name":"bad:colon",...}}]
persisted bad-named properties (verified live: HTTP 200 before this fix).

Run Hibernate Validator programmatically inside TypeRepository.prepare() so
every write path enforces the schema-derived @pattern / @SiZe / @NotNull on
each CustomProperty. The rule still lives only in basic.json — picked up via
the generated @pattern annotation, executed via ValidatorUtil.validate.

Tests in TypeResourceIT:
- test_patchCannotAddCustomPropertyWithDisallowedName — seeds a valid property
  to ensure /customProperties exists, then PATCHes appending a name with ':',
  asserts InvalidRequestException and verifies the bad name is not persisted
- test_patchCanAddCustomPropertyWithValidName — guards against the fix
  rejecting valid PATCH-driven additions
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 30 out of 32 changed files in this pull request and generated 3 comments.

Comment thread openmetadata-ui/src/main/resources/ui/src/constants/regex.constants.ts Outdated
When the property name appears in extension.<propertyName>^boost entries of
searchSettings.searchFields, OpenSearch treats * as a field-path wildcard.
The literal * field never matches its own wildcard pattern, so the field
gets silently skipped from the query and Explore search returns no hit for
the value. Bisected against the running server: of 12 candidate Lucene-special
chars, only * actually breaks the mainline UI search flow. ? ~ ( ) { } [ ] /
! and space all returned hits via the searchFields path because OS looks up
the field literally and only treats * as a wildcard at that layer.

Updates the regex + description in basic.json/customProperty.json, the UI
regex in regex.constants.ts, the validation message across 19 locales, the
generated TS docstrings, the Playwright invalid-name fixtures and spec, and
the IT TypeResourceIT case (with*asterisk moves from allowed to disallowed).
…h types

prepare() previously validated the entire customProperties[] on every Type
write. An upgraded instance with a legacy property whose name contained a
now-banned char would then reject any subsequent PUT/PATCH on that type,
even when the write only adds a different valid property. Move the name
validation into TypeUpdater.updateCustomProperties() and scope it to the
`added` list computed by recordListChange against the original entity. New
properties are still validated; pre-existing names are left alone.

Replace the IT PATCH cases' shared `topic` Type with a fresh, namespaced
entity-category Type per test (createEntityTypeForTest). The shared `topic`
was mutated concurrently by other tests in the class — combined with
PATCH's lack of per-type locking, that produced lost-update races and
flaky asserts. The fresh per-test type has customProperties: [] from
creation, so the patch sets the array directly without a seed property.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 30 out of 32 changed files in this pull request and generated 5 comments.

Comment thread openmetadata-ui/src/main/resources/ui/playwright/utils/advancedSearch.ts Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 30 out of 32 changed files in this pull request and generated 4 comments.

Comment thread openmetadata-spec/src/main/resources/json/schema/type/basic.json
Type.customProperties is a lazy field — TypeRepository.setFields only
populates it when the request URL includes ?fields=customProperties. The
default getTypeById helper omits the param, so the read-back always saw
customProperties == null. That made test_patchCanAdd... fail (the just-
persisted property wasn't visible) and made test_patchCannotAdd... pass
for the wrong reason (would have stayed green even if the bad name had
slipped through validation).

Add a fields-aware getTypeById overload and use it in both PATCH cases.
Empirically verified against the live server: good name returns 200 +
appears in customProperties, bad name returns 400 + does not.
@gitar-bot
Copy link
Copy Markdown

gitar-bot Bot commented May 5, 2026

Code Review ✅ Approved 3 resolved / 3 findings

Tightens custom property name validation with a new schema definition and Java consistency check to prevent downstream parser failures. The PR resolves previous argument order, test naming, and regex mismatch findings.

✅ 3 resolved
Bug: assertEquals arguments are swapped (expected vs actual)

📄 openmetadata-service/src/test/java/org/openmetadata/service/jdbi3/TypeRepositoryTest.java:47-49 📄 openmetadata-service/src/test/java/org/openmetadata/service/jdbi3/TypeRepositoryTest.java:63-65
JUnit's assertEquals(expected, actual, message) convention puts the expected value first and the actual value second. In both customPropertyNamePatternMatchesSchema and customPropertyNameMaxLengthMatchesSchema, the schema value (loaded at runtime) is passed as expected and the Java constant is passed as actual. This is backwards — the Java constant is the known/expected value and the schema value is what's being verified. When the assertion fails, the message will read "expected: but was: " which is confusing since the stated intent is to check the schema stays in sync with Java.

This won't cause false passes/failures, but it will produce misleading failure messages.

Bug: NAME_SUFFIX contains now-disallowed chars, will break Playwright tests

📄 openmetadata-ui/src/main/resources/ui/playwright/constant/customProperty.ts:229 📄 openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CustomProperties.spec.ts:368 📄 openmetadata-ui/src/main/resources/ui/playwright/e2e/Pages/CustomProperties.spec.ts:403
The NAME_SUFFIX constant (used to construct custom property names in Playwright CRUD tests) contains &, <, and > — all three characters that this commit now disallows in the frontend regex. The BASIC_PROPERTIES.forEach and CONFIG_PROPERTIES.forEach test loops append NAME_SUFFIX to property names, meaning those tests will now fail frontend validation when trying to create custom properties.

This is a test-breaking regression introduced by this commit.

Bug: Frontend/backend regex mismatch: &, <, > blocked in UI but allowed by backend

📄 openmetadata-ui/src/main/resources/ui/src/constants/regex.constants.ts:31-32 📄 openmetadata-spec/src/main/resources/json/schema/type/basic.json:134
The frontend CUSTOM_PROPERTY_NAME_REGEX was updated to disallow &, <, and >, but the backend JSON schema (customPropertyName in basic.json) still allows these characters in its pattern: ^[A-Za-z0-9][A-Za-z0-9 _\-.,;/&%#@!'(){}\[\]<>|=+?*~\]*$`.

This means:

  1. The UI will reject names with &, <, > but the API will still accept them — the validation is cosmetic only.
  2. Users bypassing the UI (API calls, SDK) can still create names with these characters.
  3. The error message in locales says these are "invalid characters" but the backend disagrees.

Either update the backend schema to match (if these chars truly break things), or revert the frontend change.

Options

Display: compact → Showing less information.

Comment with these commands to change:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

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

Labels

backend safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inconsistent validation for Custom Property names causes search failures with special characters

3 participants