#13960: fix(ui): preserve structured config validation error details
app: web-ui
stale
Cluster:
UI Enhancements and Security Fixes
## What this fixes
This PR improves Control UI error surfacing for config saves/updates.
In failure cases, the gateway can return structured validation details (`error.details`, often array/object with `path` + `message`). Previously, the browser client and config controller could collapse those details into opaque text, making troubleshooting much harder.
## Root cause
- `ui/src/ui/gateway.ts` rejected failed requests with only `error.message`, dropping `error.details`.
- `ui/src/ui/controllers/config.ts` used `String(err)` in catch blocks, which can turn object-shaped errors into `[object Object]`.
## Changes
1. `ui/src/ui/gateway.ts`
- Added `formatGatewayError(...)`.
- Includes `error.details` in the thrown message.
- Serializes object/array details as JSON.
2. `ui/src/ui/controllers/config.ts`
- Added `formatUiError(...)`.
- Uses `Error.message` for `Error` instances.
- JSON-serializes unknown object errors instead of `String(err)`.
3. Tests
- `ui/src/ui/gateway.node.test.ts`
- `ui/src/ui/controllers/config.node.test.ts`
## Why this helps real users
When users edit one section (e.g. `channels.qq`) but validation fails due to another section (e.g. `models.providers.*.models[].maxTokens`), the UI now shows actionable error details instead of opaque messages.
Closes #13959
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
Improved error surfacing for config operations by preserving structured validation details from gateway responses.
**Key changes:**
- Added `formatGatewayError` in `gateway.ts` to serialize `error.details` (object/array) as JSON instead of dropping them
- Added `formatUiError` in `config.ts` to JSON-serialize object errors instead of converting to `[object Object]`
- Updated error handlers in `saveConfig`, `applyConfig`, and `runUpdate` to use `formatUiError`
- Added comprehensive test coverage for both formatting functions
**Why this matters:**
When validation fails, the gateway returns structured error details (e.g., `{path: "models.providers.*.models[].maxTokens", message: "expected number"}`). Previously, these details were lost, making debugging difficult. Now they're preserved in the UI error messages.
**Scope is correct:**
Only `config.set`, `config.apply`, and `update.run` return structured validation details. The PR correctly targets only these operations. Read-only operations (`config.get`, `config.schema`) were intentionally left unchanged as they only return simple parameter validation errors.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The changes are well-scoped, defensive, and thoroughly tested. Both new formatting functions have proper error handling (try-catch with fallback to String()). The PR correctly identifies and fixes only the error handlers that can receive structured validation details. Test coverage validates the core functionality. No breaking changes or risky refactoring.
- No files require special attention
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#6352: fix(ux): update gateway token error message UI location
by Glucksberg · 2026-02-01
81.8%
#20089: fix(gateway): preserve control-ui scopes when dangerouslyDisableDev...
by vashkartik · 2026-02-18
81.3%
#13838: UI: fix config panel CI failures and modularize rendering
by fresed05 · 2026-02-11
80.8%
#5823: fix(config): exit cleanly on invalid config instead of high CPU loop
by gavinbmoore · 2026-02-01
80.7%
#9218: Fix Control UI chat resync on gaps and terminal events
by figitaki · 2026-02-05
80.3%
#21326: Security/UI: harden Control UI gatewayUrl URL overrides
by bmendonca3 · 2026-02-19
79.4%
#8546: Fix/config UI improvements
by RandomRaine · 2026-02-04
78.9%
#21609: fix(ui): align gateway connect params with ConnectParamsSchema
by sey-agent · 2026-02-20
78.6%
#8774: Fix/frontend session key normalization
by zhaodageng · 2026-02-04
78.3%
#21186: fix(gateway): strict loopback guard for Control UI (v2)
by dinakars777 · 2026-02-19
78.0%