fix(chat): unwrap raw JSON provider error payloads into readable messages#3830
fix(chat): unwrap raw JSON provider error payloads into readable messages#3830xxashxx-svg wants to merge 1 commit into
Conversation
…ages
Codex surfaces upstream error bodies verbatim as the error message string,
so the chat error banner rendered raw JSON like
{"type":"error","status":400,"error":{...}} and the unbroken token
overflowed its container.
- add extractProviderErrorMessage to @t3tools/shared that pulls the nested
human-readable message out of JSON-shaped error strings (no-op otherwise)
- apply it where codex errors become session.lastError / runtime.error
- unwrap defensively in ThreadErrorBanner for already-persisted errors and
add break-words so long unbreakable strings wrap instead of clipping
Fixes pingdotgg#3747
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Approved This PR adds a defensive utility to extract readable messages from JSON error payloads, improving error message UX. The changes are self-contained, well-tested, and don't alter when errors occur or error handling behavior - only how messages are displayed. You can customize Macroscope's approvability policy. Learn more. |
Fixes #3747
What
Model/provider errors were rendered in the chat UI as the raw upstream JSON body, e.g.
and since that string is one long unbreakable token, it also overflowed/clipped the error banner.
Why it happens
Codex fills the
error.message/turn.error.messagenotification fields with the stringified upstream response body, and t3code passes that string through verbatim intosession.lastErrorandruntime.errorevents.ThreadErrorBannerthen renders it as-is withline-clamp-3but no word-breaking, so the unwrappable token can't clamp and overflows instead.Changes
packages/shared/providerError.ts(new):extractProviderErrorMessage()— if an error string parses as JSON with amessage(or nestederror.message) field, return that; otherwise return the input unchanged. Handles double-encoded payloads. Shared module per the maintainability guidance in AGENTS.md, since both server and web need it. 8 unit tests included.apps/server(CodexSessionRuntime, CodexAdapter): apply it at the four places codex error text becomessession.lastError/turn.completed.errorMessage/runtime.error.message.apps/web(ThreadErrorBanner): unwrap defensively too (coverslastErrorvalues persisted before this fix, and any other adapter with the same habit), and addbreak-wordsto the banner + tooltip so a long unbreakable string wraps and clamps properly instead of clipping.Raw payload details are unaffected for debugging — the
runtime.errorevent still carries the original payload indetail.Before / after
With the payload above, the banner previously showed the full raw JSON (clipped); it now shows:
Checks
vp check✅vp run typecheck✅ (all 15 packages)packages/shared+ codex adapter/runtime test suites pass; the only failures inpackages/shared(logging.test.ts,relayClient.test.ts) also fail on a clean checkout ofmainon this machine (Windows env-specific) and are untouched by this PR.🤖 Generated with Claude Code
Note
Low Risk
Localized display and message normalization for Codex errors; no auth or persistence schema changes, and debugging payloads remain in event detail.
Overview
Codex often forwards stringified upstream error JSON as the user-visible message, which showed up as one long token in the chat error banner and overflowed
line-clamp-3.This PR adds
extractProviderErrorMessagein@t3tools/shared/providerError(with unit tests) to pull a human-readablemessageor nestederror.messagefrom JSON-shaped strings, including double-encoded payloads, and leaves plain text unchanged.Server: Codex
CodexAdapterandCodexSessionRuntimeapply the helper when settingturn.completed.errorMessage,runtime.error/ warning messages, andsession.lastErrorfrom turn failures and providererrornotifications.runtime.errorstill keeps the raw payload indetail.Web:
ThreadErrorBannerunwraps errors again for values stored before the server change, and addsbreak-wordson the banner and tooltip so long strings wrap and clamp correctly.Reviewed by Cursor Bugbot for commit 8d8118e. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Unwrap raw JSON provider error payloads into readable messages in chat
extractProviderErrorMessagein providerError.ts that parses JSON error bodies from providers, extracts a human-readable message string, and recursively unwraps double-encoded payloads, returning the original input unchanged for non-JSON or unrecognized formats.extractProviderErrorMessagein CodexAdapter.ts and CodexSessionRuntime.ts soturn/completedanderrorruntime events carry unwrapped messages.break-wordsto prevent long-token overflow.Macroscope summarized 8d8118e.