Skip to content

fix(chat): surface the full error in a copyable block - #2434

Merged
Dani Akash (DaniAkash) merged 2 commits into
mainfrom
fix/chat-full-error-block
Aug 25, 2026
Merged

fix(chat): surface the full error in a copyable block#2434
Dani Akash (DaniAkash) merged 2 commits into
mainfrom
fix/chat-full-error-block

Conversation

@DaniAkash

Copy link
Copy Markdown
Contributor

Problem

Chat uses the Vercel AI SDK useChat. When a turn fails, the classifier built the error envelope's details from the short constructed error.message and capped it at 500 characters. The gateway's real, actionable reason (OpenRouter-style gateways wrap it in the response body / metadata.raw) was captured at the fetch boundary as APICallError.responseBody / data.raw but never forwarded, so the user saw only a generic sentence. Errors the AI SDK could not classify carried no details at all, leaving nothing to copy or act on.

Team decision: any error that cannot be fully expressed through the AI SDK's masked stream should be shown verbatim, after scrubbing secrets, so users are empowered to fix it.

Change

  • Classifier: forward the full upstream response body (or structured data.raw), pretty-printed as JSON, into details on every path, redacted and bounded at a larger cap so the whole body survives to be copied. Errors that fall through to the generic path now carry the scrubbed raw message too.
  • Error card: render that detail always expanded under a Full error heading with a copy control. The copy targets the full string, not the DOM, so the entire error is copied even when the block clips it to a scroll area on screen. The classified title and message (credits exhausted, session expired, rate limited, and so on) stay on top, unchanged.
  • The block is omitted when the detail only repeats the message, so a clean one-line error is not duplicated.

No wire or schema change: this reuses the envelope's existing details field. The side panel and new tab share the card component, so both surfaces are covered.

Tests

  • Classifier: full response body preserved and pretty-printed in details; falls back to data.raw; secrets redacted and a pathological body bounded; a plain error surfaces its scrubbed message as copyable detail.
  • Card: the full error renders always expanded with a copy control and no toggle; the raw specifics a generic message hid are visible; the block is suppressed when it only repeats the message; the classified message stays above it.
  • Type-check and lint clean across both packages.

Follow-up

If credit exhaustion is ever returned as HTTP 200 with the error embedded in the SSE stream (rather than a 4xx the custom fetch already intercepts), the stream body would need inspecting too. The current 4xx handling covers the HTTP-error path, so that is a separate, verifiable follow-up.

When a turn fails, the classifier only forwarded the short constructed message
into the error envelope's details and capped it at 500 characters, so the
gateway's real reason (OpenRouter-style gateways hide it in the response body /
metadata.raw) never reached the user. Errors the AI SDK could not classify
carried no details at all.

Forward the full upstream response body (or structured data.raw), pretty-printed
as JSON, into details on every path, redacted and bounded at a larger cap so the
whole body survives to be copied. The card now renders that detail always
expanded under a Full error heading with a copy control that copies the entire
error even when the block clips it on screen, while the classified title and
message stay on top. The block is omitted when the detail only repeats the
message, so a clean one-line error is not shown twice.
@github-actions github-actions Bot added the fix label Aug 24, 2026
@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

✅ Tests passed: 1211/1214

Ran 8 of 15 suites (7 not affected by this change).

Suite Passed Failed Skipped
server-agent 298/298 0 0
server-api 163/163 0 0
server-tools 254/254 0 0
server-browser 10/10 0 0
server-integration 10/10 0 0
server-lib 120/120 0 0
server-root 38/41 0 3
agent 318/318 0 0
claw-app n/a n/a not affected
claw-onboard n/a n/a not affected
build n/a n/a not affected
release n/a n/a not affected
claw-server-rust n/a n/a not affected
claw-server-rust-quality n/a n/a not affected
claw-mcp n/a n/a not affected

View workflow run

@greptile-apps

greptile-apps Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This follow-up expands chat error details so users can inspect and copy scrubbed upstream responses while retaining the classified error message.

  • Raises the detail-size bound and prefers full response bodies or structured raw provider diagnostics.
  • Broadens credential redaction across several token formats and sensitive JSON fields.
  • Replaces the details toggle with an always-expanded, scrollable Full error block and clipboard control.
  • Adds server and client coverage for formatting, redaction, truncation, rendering, and copying behavior.

Confidence Score: 3/5

This PR should not merge until arbitrary upstream diagnostics are scrubbed without exposing unsupported credential formats in the error card and clipboard.

The reply from the unnamed thread participant states that the scrubber was broadened, but the current finite regex list still forwards Basic authorization and cookie/session credentials unchanged, providing a concrete residual disclosure despite that fix claim.

Files Needing Attention: packages/browseros-agent/apps/server/src/agent/chat-error.ts

Security Review

The attempted secret-scrubbing fix remains incomplete: common credentials such as Basic authorization and cookie/session values can pass through the finite regex list into the always-visible and copyable upstream error details. How this was verified: The complete redaction list lacks Basic-auth and cookie patterns while responseBody and data.raw flow through it directly to the rendered and copied details string.

Important Files Changed

Filename Overview
packages/browseros-agent/apps/server/src/agent/chat-error.ts Forwards richer upstream diagnostics and broadens redaction, but the replacement scrubber still permits common credential representations into client-visible details.
packages/browseros-agent/apps/app/screens/sidepanel/index/ChatError.tsx Formats, displays, and copies the full details string through the shared error card as intended.
packages/browseros-agent/apps/server/tests/agent/chat-error.test.ts Adds substantial coverage for upstream detail selection, formatting, truncation, and several supported secret formats.
packages/browseros-agent/apps/app/screens/sidepanel/index/ChatError.test.tsx Covers the always-expanded Full error presentation, copy control, duplicate suppression, and preservation of the classified message.
Prompt To Fix All With AI
### Issue 1
packages/browseros-agent/apps/server/src/agent/chat-error.ts:76-80
**Unsupported credentials remain exposed**

If an upstream diagnostic contains a credential such as `Authorization: Basic <base64>` or `Cookie: session=<opaque value>`, this finite regex scrubber leaves it unchanged before the response body is displayed and copied from the Full error block, exposing the credential to the user and any pasted bug report.

**How this was verified:** The complete redaction list has no Basic-auth or cookie-value rule, while `responseBody` and `data.raw` flow through it into the rendered and copied details string.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (2): Last reviewed commit: "fix(chat): broaden secret scrubbing for ..." | Re-trigger Greptile

Comment thread packages/browseros-agent/apps/server/src/agent/chat-error.ts
Forwarding the whole response body means more credential shapes can appear than
the four key patterns caught. Redact value-shaped secrets on the raw text so it
works whether or not the body parses as an object: JWTs, PEM private keys,
Google/Slack/GitLab/GitHub tokens, URL userinfo credentials (host kept), and
sensitive JSON string values matched by key name. Skewed toward over-redaction
since a missed token is copied into a bug report.
@DaniAkash

Copy link
Copy Markdown
Contributor Author

Greptile (@greptileai)

@DaniAkash Dani Akash (DaniAkash) changed the title fix(chat): surface the full scrubbed upstream error in a copyable block fix(chat): surface the full error in a copyable block Aug 24, 2026
Comment thread packages/browseros-agent/apps/server/src/agent/chat-error.ts
@DaniAkash
Dani Akash (DaniAkash) merged commit 9ab5e90 into main Aug 25, 2026
26 checks passed
@DaniAkash
Dani Akash (DaniAkash) deleted the fix/chat-full-error-block branch August 25, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant