fix: [#788] surface OpenAI nested error.message instead of Bad Request: {?:?}#789
Conversation
…st: {?:?}`
`provider/error.ts` extracted `errMsg` via `body.message || body.error || body.error?.message`. For OpenAI's standard `{error: {message, type, code}}` response shape, `body.error` short-circuits as a truthy object, the `typeof errMsg === "string"` guard fails, and the parser falls through to dumping the raw response body. Telemetry (2026-05-04) caught users seeing `APIError: Bad Request: {?:?}` (App Insights redacts string values) and retrying with the same broken model selection because the surfaced error gave no clue about the underlying cause.
Switch to an explicit-typeof ternary matching `parseStreamError`'s pattern (line 153). Now handles all three shapes safely:
- `{error: {message: "..."}}` (OpenAI) — extracts nested message
- `{message: "..."}` (Anthropic et al.) — extracts top-level message
- `{error: "..."}` (some others) — extracts string error
Wrapped in `altimate_change start — upstream_fix:` markers; upstream has the same bug. Filing upstream PR in parallel.
## Tests
Six tests added to `error.test.ts` covering:
- OpenAI nested shape extracts the inner message and does not leak the structured body
- Top-level message field still works
- Plain-string `body.error` still works
- Object `body.error` without a `message` key falls through to top-level `body.message`
- Non-string `body.error.message` (array/object) does not block a valid `body.message` (regression guard for the same class of bug)
- All-non-string-fields body falls through to raw responseBody dump (existing last-resort behavior preserved)
Suite: 386/386 provider tests pass. Typecheck clean. Marker check passes.
Reviewed by GPT 5.4, Gemini 3.1 Pro, Kimi K2.5 via /consensus:code-review — all approved with the test coverage and ternary improvements that landed before commit.
Closes #788
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR fixes error message extraction in OpenAI API response handling. The ChangesError Message Extraction Robustness
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
What does this PR do?
Fixes
provider/error.tsso OpenAI 4xx errors with the standard{error: {message, type, code}}shape surface their innermessageto the user, instead of the previous fallthrough behavior that producedAPIError: Bad Request: {?:?}(the{?:?}is the App Insights pipeline scrubbing string values from the raw structured body).The original OR-chain
body.message || body.error || body.error?.messageshort-circuited onbody.error(an object), failed thetypeof === "string"guard, and dumped the rawresponseBody. Replaced with an explicit-typeof ternary that handles the three known shapes cleanly and matchesparseStreamError's defensive pattern at line 153.Wrapped in
// altimate_change start — upstream_fix:markers per project policy. Upstream has the same bug; a parallel upstream PR is being filed so we can drop our marker if upstream takes the fix.Type of change
Issue for this PR
Closes #788
How did you verify your code works?
bun test packages/opencode/test/provider/error.test.ts— 24/24 pass (18 existing + 6 new)bun test packages/opencode/test/provider/— 386/386 pass (full provider suite)bunx tsgo --noEmit— clean (exit 0)bun run script/upstream/analyze.ts --markers --base main --strict— passes (changes wrapped in markers)/consensus:code-review— all approved with the test coverage and ternary improvements applied before commitTests added
body.messagestill works (non-regression)body.errorstill works (non-regression)body.errorwithoutmessagekey falls through to top-levelbody.messagebody.error.message(array/object) does not block a validbody.message(defensive guard for the same class of bug)responseBody(existing last-resort behavior preserved)Checklist
Summary by cubic
Fixes error message extraction for OpenAI 4xx responses by reading nested
error.messageinstead of dumping the raw body. Users now see actionable errors (e.g., model not found) instead of "Bad Request: {?:?}", meeting Linear #788.body.error.message→body.message→ stringbody.error, avoiding object short-circuits and matching stream parser behavior.responseBodywhen a valid message exists; covered by new tests.Written for commit 3a7ec72. Summary will update on new commits.
Summary by CodeRabbit
Release Notes
Bug Fixes
Tests