Skip to content

fix(web): show readable messages for structured thread errors - #9950

Open
juliusmarminge wants to merge 2 commits into
mainfrom
fix/audit-thread-error-headline
Open

fix(web): show readable messages for structured thread errors#9950
juliusmarminge wants to merge 2 commits into
mainfrom
fix/audit-thread-error-headline

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Sep 5, 2026

Copy link
Copy Markdown
Member

Related to #3747. Keep that issue open.

The chat error banner still displays raw JSON even when the response contains a useful error.message. Show that nonempty string in the headline, while retaining the exact original payload in the existing tooltip. Plain text, invalid JSON and unrecognized shapes keep their current display. Dismissal keys still use the raw payload, so different diagnostics with the same headline remain distinct.

HUMAN-HOLD: this is a proposed presentation choice. Diagnostic fields move out of the collapsed headline into the existing tooltip. Keep this PR unmerged pending human approval. It changes only the shared web/desktop banner, not mobile error details, server normalization, transport contracts, layout or word wrapping. It does not address the underlying provider errors.

Earlier message-extraction work was proposed by xxashxx-svg in #3830, which closed when orchestration V2 replaced its server paths. This narrower implementation leaves that broader normalization out. The original tiny-width layout defect did not reproduce on current main and was already addressed by #3899; the remaining raw-JSON headline did reproduce.

Verification

Both exact public JSON examples were rendered in an isolated Linux Chromium 152 client using a disposable thread. No provider or account request was made. Main 7a089b2b displayed the raw payloads. The exact candidate banner patch was then tested on 2fa5ef4c, whose intervening changes did not touch the banner.

  • At the same 366px text width, the 166-character payload becomes its complete 83-character message in two lines. The 245-character payload becomes its complete 115-character message in three lines.
  • The tooltip retains the exact original 166/245 characters without horizontal overflow. The wide-view control and native dismiss interaction pass.
  • All 30 focused banner tests pass, including both public payloads, whitespace preservation, unchanged fallbacks, one-pass extraction and raw-payload dismissal identity. Fallback shapes were verified in unit tests, not separately in the browser. No new static-markup assertions were added.
  • Focused lint, web typecheck and diff checks pass after merging current main. CI and configured reviews are tracked on the current PR head.

The original Arch/Qtile Electron and macOS desktop environments were not available. Mobile is unchanged. These limits are why this PR does not close the whole report.

Before

The multiline public payload appears as JSON in the clamped headline.

Before: raw JSON occupies the thread error banner

After

The same error shows its message at the same viewport and thread position.

After: the full nested message appears in the thread error banner

The existing tooltip still exposes the complete original diagnostic.

After: the tooltip preserves the exact original JSON payload

GPT 6 Astra via Codex in T3 Code.


Note

Low Risk
Presentation-only change in the web chat error banner with conservative parsing fallbacks and no changes to dismissal or transport behavior.

Overview
Structured API error payloads no longer fill the thread error banner headline with raw JSON. A new getThreadErrorBannerMessage helper parses JSON when possible and shows a non-empty error.message string in the clamped headline; plain text, invalid JSON, and unrecognized shapes are unchanged.

The tooltip still shows the full original error string, so diagnostics stay available without cluttering the visible line. Dismissal keys remain tied to the raw payload, so two errors with the same extracted headline (e.g. same message, different code) stay independently dismissable—covered by a new test.

Reviewed by Cursor Bugbot for commit 05a247c. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Extract nested error.message from JSON payloads in ThreadErrorBanner headline

  • Adds getThreadErrorBannerMessage utility that parses a JSON error string and returns the nested error.message when it is a non-empty string; all other inputs fall back to the original error string without recursive unwrapping
  • ThreadErrorBanner now shows the extracted message as the alert headline while the tooltip keeps the full original error string
  • Adds test coverage for single-line and multiline JSON, malformed payloads, missing fields, and dismissal-key isolation for diagnostics with the same nested message but different codes

Macroscope summarized 05a247c.

@github-actions github-actions Bot added size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.6 KiB 13.6 KiB −14 B (−0.1%) 15.1 KiB
Codex Thread snapshot wire 7.0 KiB 7.0 KiB +3 B (+0.0%) 7.3 KiB
Codex Live turn WebSocket wire 6.6 KiB 6.6 KiB −17 B (−0.3%) 7.8 KiB
Codex Live turn WebSocket decoded 57.1 KiB 57.1 KiB 0 B (0.0%) 66.4 KiB
Codex Live turn messages 10 10 0 (0.0%) 21
Claude Total thread wire 13.6 KiB 13.6 KiB +21 B (+0.2%) 15.1 KiB
Claude Thread snapshot wire 7.0 KiB 7.0 KiB −5 B (−0.1%) 7.3 KiB
Claude Live turn WebSocket wire 6.5 KiB 6.6 KiB +26 B (+0.4%) 7.8 KiB
Claude Live turn WebSocket decoded 57.9 KiB 57.9 KiB 0 B (0.0%) 66.4 KiB
Claude Live turn messages 10 10 0 (0.0%) 21

Baseline: 2fa5ef4 · PR result: 05a247c · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 113.8 KiB
  • Claude decoded thread snapshot: 114.5 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

macroscopeapp Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 05a247c

Macroscope's review found this PR approvable — This is a small, self-contained web UI fix that replaces raw structured error JSON with its readable nested message while preserving the original payload in the tooltip and dismissal behavior. Tests cover the extraction and fallback cases, with no schema, configuration, security, billing, or deployment impact.

You can add or adjust custom eligibility rules. Learn more.

@juliusmarminge

Copy link
Copy Markdown
Member Author

Preparation is complete at 05a247c5, against 2fa5ef4c. All executed CI checks pass, including Bugbot, correctness, UI consistency and automated approvability. Skipped checks remain skipped. The complete current-head review snapshot has no unresolved threads or change requests. The 30 focused tests, lint, web typecheck and approved before/after evidence are recorded above.

HUMAN-HOLD remains. Automated eligibility does not decide whether diagnostic fields should move from the headline into the existing tooltip. This PR stays unmerged for that presentation decision, and #3747 stays open with its native-platform and mobile limits. No server normalization or layout behavior changed.

GPT 6 Astra via Codex in T3 Code.

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

Labels

size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant