Skip to content

Fix(UI): Send a single, minimal PATCH when updating a Data Product's domain#27598

Merged
siddhant1 merged 4 commits intomainfrom
fix/data-product-domain-single-patch
Apr 22, 2026
Merged

Fix(UI): Send a single, minimal PATCH when updating a Data Product's domain#27598
siddhant1 merged 4 commits intomainfrom
fix/data-product-domain-single-patch

Conversation

@siddhant1
Copy link
Copy Markdown
Member

@siddhant1 siddhant1 commented Apr 21, 2026

Summary

  • DataProductDomainWidget now delegates to the page-level handleDataProductUpdate via onUpdate, matching the DomainLabelV2.handleDomainSave convention — so one PATCH /api/v1/dataProducts/{id} with a single replace /domains op fires per domain change, instead of two.
  • The second PATCH previously diffed stale UI state against the server response returned by the first PATCH and emitted ops on /impersonatedBy, /changeDescription, /version. fge's JsonPatch.apply threw "Non-existing name/value pair in the object for key impersonatedBy" on the /impersonatedBy op and aborted the whole request.
  • Domain refs in the patch are now trimmed to {id, type, name, fullyQualifiedName}; the backend resolves the full EntityReference via EntityRepository.getValidatedDomains(…).

Summary by Gitar

  • Error handling:
    • Updated DataProductDomainWidget to rethrow errors from onUpdate to ensure callers can block optimistic UI updates on failure.
  • Test improvements:
    • Added a unit test in DataProductDomainWidget.test.tsx to verify that onUpdate failures are correctly rethrown.
    • Cleaned up unused mockShowErrorToast dependencies in the test suite.

This will update automatically on new commits.

…domain

DataProductDomainWidget now delegates to the page-level handleDataProductUpdate
via onUpdate, matching the DomainLabelV2 convention, so one PATCH with a single
replace /domains op is sent instead of two. The second PATCH previously diffed
stale context against the server response and emitted operations on
/impersonatedBy, /changeDescription, /version — the /impersonatedBy op failed
inside fge JsonPatch with "Non-existing name/value pair in the object for key
impersonatedBy".

Domain refs in the patch are trimmed to {id, type, name, fullyQualifiedName};
the backend resolves the full EntityReference via getValidatedDomains. Adds
jest coverage for the widget and a Playwright regression test that asserts
exactly one PATCH per domain change and validates the minimal payload shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 21, 2026 15:03
@siddhant1 siddhant1 requested a review from a team as a code owner April 21, 2026 15:03
@github-actions
Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

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

Note

Copilot was unable to run its full agentic suite in this review.

Adjusts the Data Product domain editor to delegate updates to the page-level update handler so the UI emits a single minimal PATCH /dataProducts/{id} per domain change (avoiding stale diff-based extra ops that caused backend JsonPatch exceptions).

Changes:

  • Remove direct patchDataProduct(compare(...)) flow from DataProductDomainWidget and instead call the context onUpdate with trimmed domain references.
  • Add Jest coverage ensuring the widget delegates via onUpdate and strips domain ref fields.
  • Add a Playwright regression test asserting exactly one minimal PATCH is sent when changing a Data Product’s domain.

Reviewed changes

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

File Description
openmetadata-ui/src/main/resources/ui/src/components/DataProducts/DataProductDomainWidget/DataProductDomainWidget.tsx Stops self-patching and delegates to page-level update with minimal domains refs.
openmetadata-ui/src/main/resources/ui/src/components/DataProducts/DataProductDomainWidget/DataProductDomainWidget.test.tsx Adds unit tests verifying delegation and domain ref stripping.
openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/DataProductDomainMigration.spec.ts Adds e2e regression test for single minimal PATCH behavior.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 61%
62.02% (60342/97290) 42.02% (31636/75281) 45.04% (9502/21095)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

🟡 Playwright Results — all passed (12 flaky)

✅ 3699 passed · ❌ 0 failed · 🟡 12 flaky · ⏭️ 89 skipped

Shard Passed Failed Flaky Skipped
✅ Shard 1 481 0 0 4
🟡 Shard 2 655 0 1 7
🟡 Shard 3 665 0 1 1
🟡 Shard 4 643 0 5 27
✅ Shard 5 611 0 0 42
🟡 Shard 6 644 0 5 8
🟡 12 flaky test(s) (passed on retry)
  • Features/BulkEditEntity.spec.ts › Glossary (shard 2, 1 retry)
  • Features/RTL.spec.ts › Verify Following widget functionality (shard 3, 1 retry)
  • Pages/Customproperties-part2.spec.ts › entityReferenceList shows item count, scrollable list, no expand toggle (shard 4, 1 retry)
  • Pages/DataContracts.spec.ts › Create Data Contract and validate for Api Collection (shard 4, 1 retry)
  • Pages/DataContracts.spec.ts › Create Data Contract and validate for Spreadsheet (shard 4, 1 retry)
  • Pages/Domains.spec.ts › Domain Rbac (shard 4, 1 retry)
  • Pages/Entity.spec.ts › User as Owner with unsorted list (shard 4, 1 retry)
  • Pages/HyperlinkCustomProperty.spec.ts › should display URL when no display text is provided (shard 6, 1 retry)
  • Pages/Lineage/DataAssetLineage.spec.ts › verify create lineage for entity - Dashboard (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/Users.spec.ts › Permissions for table details page for Data Consumer (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

Siddhant and others added 2 commits April 22, 2026 11:02
…ation

The new "Changing data product domain via UI fires a single minimal PATCH"
Playwright case timed out across all retries on CI. The selectors borrowed from
assignDomain don't match the DataProductDomainWidget's mounted variant of
DomainLabelV2 + DomainSelectableList, and the rest of this spec already drives
state via API patches rather than the picker UI.

The widget-level jest test (DataProductDomainWidget.test.tsx) already proves
the regression: it asserts patchDataProduct is never called and that onUpdate
receives a DataProduct with minimal {id, type, name, fullyQualifiedName}
domain refs. That coverage is sufficient for the patch-shape regression.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.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.

Pull request overview

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

…pdates on failure

Agent-Logs-Url: https://github.com/open-metadata/OpenMetadata/sessions/6c1731fa-0f99-423e-828c-afbff35bd885

Co-authored-by: siddhant1 <30566406+siddhant1@users.noreply.github.com>
auto-merge was automatically disabled April 22, 2026 05:52

Head branch was pushed to by a user without write access

@gitar-bot
Copy link
Copy Markdown

gitar-bot Bot commented Apr 22, 2026

Code Review 👍 Approved with suggestions 0 resolved / 1 findings

Updates to the Data Product domain successfully reduce network traffic to a single PATCH request. Consider providing user feedback instead of a silent no-op when the update handler is falsy.

💡 Edge Case: Silent no-op when onUpdate is falsy (dead-code guard)

📄 openmetadata-ui/src/main/resources/ui/src/components/DataProducts/DataProductDomainWidget/DataProductDomainWidget.tsx:65-67

The new guard if (!dataProduct || !onUpdate) at line 65 silently returns without feedback if onUpdate is falsy. Since onUpdate is a required prop in GenericProviderProps and is always provided by DataProductsDetailsPage, the !onUpdate check is dead code. It's not harmful, but it could mask bugs if the provider contract ever changes — consider removing the !onUpdate guard (TypeScript already enforces it) or, if kept, logging/toasting so the user isn't left wondering why nothing happened.

🤖 Prompt for agents
Code Review: Updates to the Data Product domain successfully reduce network traffic to a single PATCH request. Consider providing user feedback instead of a silent no-op when the update handler is falsy.

1. 💡 Edge Case: Silent no-op when onUpdate is falsy (dead-code guard)
   Files: openmetadata-ui/src/main/resources/ui/src/components/DataProducts/DataProductDomainWidget/DataProductDomainWidget.tsx:65-67

   The new guard `if (!dataProduct || !onUpdate)` at line 65 silently returns without feedback if `onUpdate` is falsy. Since `onUpdate` is a required prop in `GenericProviderProps` and is always provided by `DataProductsDetailsPage`, the `!onUpdate` check is dead code. It's not harmful, but it could mask bugs if the provider contract ever changes — consider removing the `!onUpdate` guard (TypeScript already enforces it) or, if kept, logging/toasting so the user isn't left wondering why nothing happened.

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

@siddhant1 siddhant1 merged commit 3940447 into main Apr 22, 2026
78 of 85 checks passed
@siddhant1 siddhant1 deleted the fix/data-product-domain-single-patch branch April 22, 2026 08:58
@github-actions
Copy link
Copy Markdown
Contributor

Changes have been cherry-picked to the 1.12.6 branch.

github-actions Bot pushed a commit that referenced this pull request Apr 22, 2026
…domain (#27598)

* Fix(UI): Send a single, minimal PATCH when updating a Data Product's domain

DataProductDomainWidget now delegates to the page-level handleDataProductUpdate
via onUpdate, matching the DomainLabelV2 convention, so one PATCH with a single
replace /domains op is sent instead of two. The second PATCH previously diffed
stale context against the server response and emitted operations on
/impersonatedBy, /changeDescription, /version — the /impersonatedBy op failed
inside fge JsonPatch with "Non-existing name/value pair in the object for key
impersonatedBy".

Domain refs in the patch are trimmed to {id, type, name, fullyQualifiedName};
the backend resolves the full EntityReference via getValidatedDomains. Adds
jest coverage for the widget and a Playwright regression test that asserts
exactly one PATCH per domain change and validates the minimal payload shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Drop flaky UI single-PATCH Playwright case from DataProductDomainMigration

The new "Changing data product domain via UI fires a single minimal PATCH"
Playwright case timed out across all retries on CI. The selectors borrowed from
assignDomain don't match the DataProductDomainWidget's mounted variant of
DomainLabelV2 + DomainSelectableList, and the rest of this spec already drives
state via API patches rather than the picker UI.

The widget-level jest test (DataProductDomainWidget.test.tsx) already proves
the regression: it asserts patchDataProduct is never called and that onUpdate
receives a DataProduct with minimal {id, type, name, fullyQualifiedName}
domain refs. That coverage is sufficient for the patch-shape regression.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: rethrow errors in performDomainUpdate to prevent optimistic UI updates on failure

Agent-Logs-Url: https://github.com/open-metadata/OpenMetadata/sessions/6c1731fa-0f99-423e-828c-afbff35bd885

Co-authored-by: siddhant1 <30566406+siddhant1@users.noreply.github.com>

---------

Co-authored-by: Siddhant <siddhant@MacBook-Pro-621.local>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
(cherry picked from commit 3940447)
jatinmasaram pushed a commit to jatinmasaram/OpenMetadata that referenced this pull request May 2, 2026
…domain (open-metadata#27598)

* Fix(UI): Send a single, minimal PATCH when updating a Data Product's domain

DataProductDomainWidget now delegates to the page-level handleDataProductUpdate
via onUpdate, matching the DomainLabelV2 convention, so one PATCH with a single
replace /domains op is sent instead of two. The second PATCH previously diffed
stale context against the server response and emitted operations on
/impersonatedBy, /changeDescription, /version — the /impersonatedBy op failed
inside fge JsonPatch with "Non-existing name/value pair in the object for key
impersonatedBy".

Domain refs in the patch are trimmed to {id, type, name, fullyQualifiedName};
the backend resolves the full EntityReference via getValidatedDomains. Adds
jest coverage for the widget and a Playwright regression test that asserts
exactly one PATCH per domain change and validates the minimal payload shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Drop flaky UI single-PATCH Playwright case from DataProductDomainMigration

The new "Changing data product domain via UI fires a single minimal PATCH"
Playwright case timed out across all retries on CI. The selectors borrowed from
assignDomain don't match the DataProductDomainWidget's mounted variant of
DomainLabelV2 + DomainSelectableList, and the rest of this spec already drives
state via API patches rather than the picker UI.

The widget-level jest test (DataProductDomainWidget.test.tsx) already proves
the regression: it asserts patchDataProduct is never called and that onUpdate
receives a DataProduct with minimal {id, type, name, fullyQualifiedName}
domain refs. That coverage is sufficient for the patch-shape regression.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: rethrow errors in performDomainUpdate to prevent optimistic UI updates on failure

Agent-Logs-Url: https://github.com/open-metadata/OpenMetadata/sessions/6c1731fa-0f99-423e-828c-afbff35bd885

Co-authored-by: siddhant1 <30566406+siddhant1@users.noreply.github.com>

---------

Co-authored-by: Siddhant <siddhant@MacBook-Pro-621.local>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs To release Will cherry-pick this PR into the release branch UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants