fix(chutes): bound OAuth token error response reads#97808
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 29, 2026, 11:25 AM ET / 15:25 UTC. Summary PR surface: Source +2, Tests +78. Total +80 across 2 files. Reproducibility: yes. Current main has source-visible unbounded Review metrics: none identified. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Next step before merge
Security Review detailsBest possible solution: Land the owner-local bounded-read fix once normal maintainer review is complete; no broader OAuth refactor or new config surface is needed. Do we have a high-confidence way to reproduce the issue? Yes. Current main has source-visible unbounded Is this the best way to solve the issue? Yes. Reusing the existing bounded reader in the two owner-local token error branches matches sibling Chutes plugin and MiniMax OAuth patterns without adding new API or config surface. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 1052652a7168. Label changesLabel justifications:
Evidence reviewedPR surface: Source +2, Tests +78. Total +80 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
Updated the PR body with real-behavior proof: the real exported @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Co-Authored-By: Claude Opus 4.8 <[email protected]>
* fix(chutes): bound OAuth token error response reads * ci: re-trigger checks (fs-safe unhandled-rejection flake on prior run) Co-Authored-By: Claude Opus 4.8 <[email protected]> --------- Co-authored-by: Pick-cat <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]>
* fix(chutes): bound OAuth token error response reads * ci: re-trigger checks (fs-safe unhandled-rejection flake on prior run) Co-Authored-By: Claude Opus 4.8 <[email protected]> --------- Co-authored-by: Pick-cat <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]>
* fix(chutes): bound OAuth token error response reads * ci: re-trigger checks (fs-safe unhandled-rejection flake on prior run) Co-Authored-By: Claude Opus 4.8 <[email protected]> --------- Co-authored-by: Pick-cat <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]>
* fix(chutes): bound OAuth token error response reads * ci: re-trigger checks (fs-safe unhandled-rejection flake on prior run) Co-Authored-By: Claude Opus 4.8 <[email protected]> --------- Co-authored-by: Pick-cat <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]>
* fix(chutes): bound OAuth token error response reads * ci: re-trigger checks (fs-safe unhandled-rejection flake on prior run) Co-Authored-By: Claude Opus 4.8 <[email protected]> --------- Co-authored-by: Pick-cat <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]> (cherry picked from commit 9949f6b)
What Problem This Solves
Chutes OAuth token exchange and refresh failures read the error body with an unbounded
await response.text(). On a hostile or misconfigured token endpoint (https://api.chutes.ai/idp/token) that streams a large body with noContent-Length, the gateway buffers the entire payload into memory before surfacing the error — a memory-pressure / OOM vector during auth setup and token refresh.Affected surface:
src/agents/chutes-oauth.ts—exchangeChutesCodeForTokensandrefreshChutesTokenserror paths.Why This Change Was Made
Successful Chutes JSON token responses are already bounded via
readProviderJsonResponse, but the two!response.okbranches still calledresponse.text()directly. This change routes those reads through the existing shared bounded readerreadResponseTextLimitedwith an 8 KiB cap (CHUTES_OAUTH_ERROR_BODY_LIMIT_BYTES), matching the MiniMax OAuth error-handling pattern. The reader stops pulling and cancels the upstream stream once the diagnostic budget is full, so the surfaced error snippet stays useful while the body can no longer grow without bound.No new abstraction — reuses the existing
readResponseTextLimitedhelper. One concern, two call sites;chutes-oauth.tsdoes not touch fs-safe or any other surface.User Impact
Operators configuring or refreshing Chutes OAuth credentials still get the same actionable error snippet on token failures, but the gateway can no longer be driven to buffer an arbitrarily large error body into memory by a hostile or broken token endpoint.
Evidence
1. Real-behavior proof with a negative control. A harness drives the real exported
exchangeChutesCodeForTokens/refreshChutesTokensagainst a realnode:httpserver on127.0.0.1that streams a 25 MiB error body in chunks with noContent-Length, and measures bytes actually flushed on the wire before the socket closes. The negative control runs the pre-fixawait response.text()against the same server.Without the fix the error read returns the full 25.03 MiB body; with the fix the surfaced snippet is capped at 8222 bytes and the server flushes only 0.21 MiB before the client cancels the stream and the socket closes — proving the cap is load-bearing, not incidental. The residual ~0.21 MiB is in-flight TCP/socket buffering, not buffered by the reader.
2. Committed regression tests (
src/agents/chutes-oauth.flow.test.ts) cover both call sites: they stream an oversized error body through a trackedReadableStream, spy onresponse.text()to assert it is never called, and assert the stream is canceled after the bounded read.3. Lint + types on the changed file:
What was NOT tested: I did not hit the live Chutes endpoint and did not drive the process to an actual OOM. The cap is proven by bytes-on-wire + early socket close against a local server reproducing the unbounded-stream condition, plus the negative control showing the old path buffering the full body.
AI-assisted: implementation, tests, and the proof harness were drafted with agent assistance; all commands above were run locally.
Fixes the unbounded Chutes OAuth error-body read.