Skip to content

fix(ui): resolve metadata agent form crash and manifest JSON editor UX#30141

Open
aniketkatkar97 wants to merge 10 commits into
mainfrom
s3-widget-error-metadata-agent
Open

fix(ui): resolve metadata agent form crash and manifest JSON editor UX#30141
aniketkatkar97 wants to merge 10 commits into
mainfrom
s3-widget-error-metadata-agent

Conversation

@aniketkatkar97

@aniketkatkar97 aniketkatkar97 commented Jul 16, 2026

Copy link
Copy Markdown
Member

Fixes #30142

Problem

Adding or editing a metadata agent for a Storage (S3) service crashed the UI:

Error: Unsupported widget definition: object
    at getWidget (@rjsf/utils)

IngestionWorkflowForm registers its RJSF widgets as raw React.lazy(...) objects. @rjsf/utils getWidget (v5.24.13) accepts only function / forwardRef / memo / string — a React.lazy result is a plain object, so resolving the storage defaultManifest → ui:widget: 'manifestJson' threw. Introduced by #28569, which switched this form's widgets to React.lazy.

Testing the (now-rendering) Default Manifest editor surfaced three more UX bugs: it was half-width, the caret jumped while typing, and clearing it reverted to the sample JSON.

Changes

Crash fix

  • IngestionWorkflowForm: wrap the lazy RJSF widgets in the existing withSuspenseFallback HOC (returns a forwardRef, which getWidget accepts) so they resolve while keeping code-splitting. Same pattern MetadataAgentsWidget already uses.

Manifest JSON editor

  • Full widthIngestionObjectFieldTemplate.isWide() now treats uiFieldType: 'code' fields as full-row (generic, no hardcoded field name).
  • No caret jumpSchemaEditor gains an autoFormat prop (default true, existing consumers unchanged); ManifestJsonWidget sets autoFormat={false} so the buffer is not re-indented via JSON.stringify on every keystroke.
  • No stale default — the sample manifest is shown as a CodeMirror placeholder (muted --tw-color-text-placeholder, multi-line via pre-wrap, editor flex-fills its wrapper) instead of being written as the field value. Clearing the editor now leaves it truly empty.

Testing

  • Playwright (StorageMetadataAgentForm.spec.ts): edit form renders without crashing, manifest edits save (asserted on the PATCH /services/ingestionPipelines/{id} response) and round-trip on reopen; editor is full width, clears cleanly (placeholder muted + multi-line), and the caret stays stable (no live re-format). Verified end-to-end against a local backend + Airflow.
  • Unit — new SchemaEditor.utils.test.ts covers getSchemaEditorValue (both autoFormat modes + edge cases); ManifestJsonWidget tests updated to the placeholder contract; existing validateManifestJson coverage unchanged. jest → 33 passing.

🤖 Generated with Claude Code

Greptile Summary

This PR fixes the metadata-agent form crash and improves the manifest JSON editor. The main changes are:

  • Wraps lazy RJSF widgets in Suspense-enabled components.
  • Adds an uncontrolled editor mode to preserve caret position.
  • Shows the sample manifest as a placeholder instead of form data.
  • Makes code fields span the full form width.
  • Adds unit and end-to-end coverage for the updated workflow.

Confidence Score: 5/5

This looks safe to merge.

  • The previously reported checkstyle failure is fixed.
  • No remaining issue qualifies for a follow-up comment.

Important Files Changed

Filename Overview
openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/Ingestion/IngestionWorkflowForm/IngestionWorkflowForm.tsx Wraps lazy widgets in Suspense-enabled forwardRef components accepted by RJSF.
openmetadata-ui/src/main/resources/ui/src/components/Database/SchemaEditor/SchemaEditor.tsx Adds optional formatting and uncontrolled buffer ownership while preserving existing defaults.
openmetadata-ui/src/main/resources/ui/src/components/common/Form/JSONSchema/JsonSchemaWidgets/ManifestJsonWidget/ManifestJsonWidget.tsx Uses an empty editor value with a sample placeholder and disables live formatting.
openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/StorageMetadataAgentForm.spec.ts Covers rendering, editing, persistence, clearing, layout, and caret behavior.

Reviews (6): Last reviewed commit: "Merge branch 'main' into s3-widget-error..." | Re-trigger Greptile

Context used (3)

  • Context used - CLAUDE.md (source)
  • Context used - openmetadata-ui-core-components/CLAUDE.md (source)
  • Context used - AGENTS.md (source)

The add/edit metadata agent form crashed with "Unsupported widget
definition: object" for Storage (S3) services. IngestionWorkflowForm
registered its RJSF widgets as raw React.lazy objects; @rjsf/utils
getWidget accepts only function/forwardRef/memo, so resolving the
manifestJson widget threw. Wrap the lazy widgets in the existing
withSuspenseFallback (forwardRef) so getWidget accepts them while keeping
code-splitting.

Also fixes the Default Manifest JSON editor:
- Full width: isWide() now treats uiFieldType 'code' fields as wide.
- No caret jump: SchemaEditor gains an autoFormat prop (default true); the
  manifest widget disables it so the buffer is not re-indented on every
  keystroke.
- No stale default: the sample is shown as a CodeMirror placeholder
  (muted --tw-color-text-placeholder, multi-line, editor flex-fills its
  wrapper) instead of being written as the field value.

Adds a Playwright spec (render + edit/save round-trip, width, clears
cleanly, caret stability) and unit tests for getSchemaEditorValue; updates
ManifestJsonWidget tests to the placeholder contract.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 12:17
@aniketkatkar97
aniketkatkar97 requested a review from a team as a code owner July 16, 2026 12:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 has reached their quota limit.

@github-actions github-actions Bot added safe to test Add this label to run secure Github workflows on PRs UI UI specific issues labels Jul 16, 2026
@open-metadata open-metadata deleted a comment from github-actions Bot Jul 16, 2026
Copilot AI review requested due to automatic review settings July 16, 2026 12:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 has reached their quota limit.

@open-metadata open-metadata deleted a comment from github-actions Bot Jul 16, 2026
Satisfies the space-after-comment lint rule flagged in review.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 12:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 has reached their quota limit.

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 64%
65.02% (75555/116197) 48.85% (45042/92201) 49.63% (13623/27449)

react-codemirror2's Controlled mode cancels CodeMirror's native change and
re-applies the value, which drops the caret that autoCloseBrackets places
between the inserted pair (typing `{` produced `{}` with the caret after `}`,
so the next character landed outside).

Add an opt-in `uncontrolled` mode to SchemaEditor that renders the UnControlled
CodeMirror so the editor owns its buffer and caret. The value prop is used only
as initial content; external updates (e.g. an async-loaded saved config) are
synced imperatively while the editor is blurred so active typing is never
disturbed. ManifestJsonWidget opts in.

Adds a Playwright assertion that typing `{` then `x` yields `{x}`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 12:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 has reached their quota limit.

Address review edge case: an external value arriving while the uncontrolled
editor is focused was skipped by the blurred-only sync and never re-applied.
Track the latest value and apply it on the next blur.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 12:57
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

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

✅ 4548 passed · ❌ 1 failed · 🟡 24 flaky · ⏭️ 96 skipped

Shard Passed Failed Flaky Skipped
🟡 Shard 1 437 0 3 16
✅ Shard 2 11 0 0 0
🟡 Shard 3 825 0 8 8
🟡 Shard 4 820 0 3 18
🟡 Shard 5 842 0 1 5
🟡 Shard 6 786 0 2 46
🔴 Shard 7 827 1 7 3

Genuine Failures (failed on all attempts)

Features/AutoPilot.spec.ts › Create Service and check the AutoPilot status (shard 7)
Error: �[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m(�[22m�[2m)�[22m failed

Locator: getByText('AutoPilot agents run completed successfully.')
Expected: visible
Timeout: 60000ms
Error: element(s) not found

Call log:
�[2m  - Expect "toBeVisible" with timeout 60000ms�[22m
�[2m  - waiting for getByText('AutoPilot agents run completed successfully.')�[22m

🟡 24 flaky test(s) (passed on retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab IS visible for supported type: metric (shard 1, 1 retry)
  • Pages/SearchSettings.spec.ts › Latest preview config wins when a superseded request resolves late (shard 1, 1 retry)
  • Flow/SearchRBAC.spec.ts › a fully denied user sees neither asset type when browsing (shard 1, 1 retry)
  • Features/BulkEditEntity.spec.ts › Database (shard 3, 1 retry)
  • Features/BulkEditOperationBadges.spec.ts › Database service bulk edit search filters rows and clear restores them (shard 3, 1 retry)
  • Features/BulkImportWithDotInName.spec.ts › Column with dot in name under service with dot (shard 3, 1 retry)
  • Features/ContextCenterArchive.spec.ts › archive page lazy-loads more rows on scroll within its own scroll container (shard 3, 1 retry)
  • Features/ContextCenterArticles.spec.ts › Article listing search filters, clears, and shows empty state (shard 3, 1 retry)
  • Features/ContextCenterArticles.spec.ts › Article list cards, recently viewed widget, and pagination work (shard 3, 1 retry)
  • Features/ContextCenterArticles.spec.ts › description: switching articles does not bleed unsaved content into next article (shard 3, 1 retry)
  • Features/ContextCenterMemories.spec.ts › clearing search restores the unfiltered list (shard 3, 1 retry)
  • Features/Glossary/GlossaryTermRelationsGraphNested.spec.ts › viewing a child term: parent appears as a 1-hop neighbour via parentOf edge (shard 4, 1 retry)
  • Features/Glossary/GlossaryTermRelationsGraphNested.spec.ts › viewing a child term: parentOf edge is rendered between parent and child (shard 4, 1 retry)
  • Features/Table.spec.ts › should persist page size (shard 4, 1 retry)
  • Pages/DataContractsSemanticRules.spec.ts › Validate Owner Rule Not_In (shard 5, 1 retry)
  • Pages/ExploreBrowse.spec.ts › service type drill-down disables unrelated roots and query-panel Clear resets it (shard 6, 1 retry)
  • Pages/ExplorePageRightPanel_KnowledgeCenter.spec.ts › Should remove user owner for knowledgeCenter (shard 6, 1 retry)
  • Pages/Glossary.spec.ts › Approve and reject glossary term from Glossary Listing (shard 7, 2 retries)
  • Pages/GlossaryImportExport.spec.ts › Check for Circular Reference in Glossary Import (shard 7, 1 retry)
  • Pages/GlossaryImportExport.spec.ts › Import partial success - some terms pass, some fail (shard 7, 1 retry)
  • Pages/Lineage/LineageFilters.spec.ts › Verify Impact Analysis service filter selection (shard 7, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab is NOT visible for pipelineService in platform lineage (shard 7, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab is NOT visible for apiService in platform lineage (shard 7, 1 retry)
  • Pages/TasksUIFlow.spec.ts › Create and reject tag task for Dashboard via UI (shard 7, 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 July 17, 2026 12:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 has reached their quota limit.

Copilot AI review requested due to automatic review settings July 17, 2026 13:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 has reached their quota limit.

Copilot AI review requested due to automatic review settings July 17, 2026 13:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 has reached their quota limit.

@gitar-bot

gitar-bot Bot commented Jul 17, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 1 resolved / 1 findings

Resolves the metadata agent form crash by wrapping lazy RJSF widgets in suspense fallbacks and improves manifest JSON editor UX with stable caret handling and proper placeholder support. No issues found.

✅ 1 resolved
Edge Case: Uncontrolled sync skips value updates that arrive while focused

📄 openmetadata-ui/src/main/resources/ui/src/components/Database/SchemaEditor/SchemaEditor.tsx:145-153
The uncontrolled-mode sync effect only pushes an external value change into the editor when it is blurred, and it only runs when [value, autoFormat, uncontrolled] change. If a new value (e.g. an async-loaded saved config) arrives while the editor is focused, the effect skips the update and never re-runs on blur, leaving the editor showing stale content. This is a narrow case since the user must already be focused when the async load resolves. If needed, track focus/pending state so the deferred value is applied on the next blur.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqubecloud

Copy link
Copy Markdown

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 UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S3 metadata agent form crashes: "Unsupported widget definition: object"

2 participants