Skip to content

fix(web-ui): render localized setup-field labels in the plugin config drawer - #917

Merged
Weegy merged 2 commits into
mainfrom
worktree-fix-plugin-config-drawer-localized-labels
Aug 28, 2026
Merged

fix(web-ui): render localized setup-field labels in the plugin config drawer#917
Weegy merged 2 commits into
mainfrom
worktree-fix-plugin-config-drawer-localized-labels

Conversation

@Weegy

@Weegy Weegy commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Problem

Clicking Config on a plugin attached to an orchestrator (/operator/agents/<slug>) replaced the entire page with the route error boundary — „Etwas ist schiefgelaufen".

Reproduced live on odoo-bot-harness.fly.dev; the captured console error is unambiguous:

Minified React error #31 … args[]=object with keys {en}
  → [web-ui] route error boundary caught

Root cause

Since #602 (OM-17) manifestLoader normalises every setup field's label and help into a { <locale>: text } map (normalizeLocalized(f['label']) ?? { en: key }). The store's setup form and credentials editor were updated to resolve those with pickLocalized. PluginsDnd was not — it still rendered field.label straight into JSX, which is React #31 "Objects are not valid as a React child". The throw happens on the first render after the drawer opens, so it propagates to app/error.tsx.

PluginSetupFieldDto declared label: string / help?: string, which is precisely why typecheck never caught the drift against the real payload.

This was not an edge case. Scanning the live /plugin-catalog response: 192 of 192 setup fields across 27 plugins are maps — not a single one ships a bare string. Every plugin with setup fields was unconfigurable from the orchestrator page.

Changes

File Change
PluginsDnd.tsx Resolve label/help via pickLocalized(…, useLocale()), falling back to field.key exactly as the loader does
_lib/agents.ts PluginSetupFieldDto.label/helpLocalizedMarkdown | string
_lib/localized.ts pickLocalized returns a bare string as-is — without that branch a pre-#602 payload would fall through to Object.values('abc') and render 'a'
__tests__/PluginsDnd.localizedFields.test.tsx New regression test

Test plan

  • New test: drawer opens, map resolves, active locale wins, bare string still renders, empty map falls back to the key
  • Negative control — reverting only the render change fails 3 of the 4 with the exact React chore: apply byte5ai engineering-standards (initial bootstrap) #31 message
  • npm run typecheck clean
  • npm run lint — 0 errors (52 pre-existing warnings)
  • npm run i18n:check — OK, 4086 keys
  • Full web-ui suite — 998/998 passed (110 files)
  • Post-merge: re-verify the drawer on the harness deployment

No new user-facing strings; the labels come from plugin manifests, so no messages/*.json change is involved.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Weegy added 2 commits August 28, 2026 12:34
… drawer

Clicking "Config" on a plugin attached to an orchestrator replaced the whole
page with the route error boundary ("Etwas ist schiefgelaufen").

Root cause: since #602 (OM-17) the manifest loader normalises every setup
field's `label` and `help` into a `{ <locale>: text }` map (`?? { en: key }`).
PluginsDnd still rendered `field.label` straight into JSX, which is React #31
("Objects are not valid as a React child (found: object with keys {en})"). It
threw on the first render after the drawer opened, so the error propagated to
app/error.tsx and took the orchestrator page down.

This was not an edge case: 192 of 192 setup fields across 27 plugins in the
live catalog are maps — not one ships a bare string. Every plugin with setup
fields was unconfigurable from the orchestrator page.

- PluginsDnd resolves label/help with `pickLocalized` (the same helper the
  store's setup form and credentials editor already use), falling back to the
  field key exactly as the loader does.
- `PluginSetupFieldDto` typed `label`/`help` as plain strings, which is what
  let the mismatch through typecheck; both are now `LocalizedMarkdown | string`.
- `pickLocalized` now returns a bare string as-is. Without that branch a
  payload from a pre-#602 middleware would fall through to
  `Object.values('abc')` and render 'a'.

Regression test drives the button and asserts the map resolves, the active
locale wins, a bare string still renders, and an empty map falls back to the
key. Reverting the render change fails three of the four with React #31.
@Weegy
Weegy merged commit 8d6bd4b into main Aug 28, 2026
8 checks passed
@Weegy
Weegy deleted the worktree-fix-plugin-config-drawer-localized-labels branch August 28, 2026 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant