fix(provider-usage): bound usage JSON response reads to prevent OOM#97610
fix(provider-usage): bound usage JSON response reads to prevent OOM#97610cxbAsDev wants to merge 1 commit into
Conversation
Replace unbounded response.json() with readProviderJsonResponse in readUsageJson to cap provider usage API response bodies at 16 MiB, preventing unbounded buffering from all seven providers (claude, gemini, codex, z.ai, deepseek, minimax, and openai-compatible). Co-Authored-By: Claude <[email protected]>
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as duplicate/superseded because #96360 already owns the same shared provider-usage JSON OOM fix with focused tests, sufficient proof, and a ready-for-maintainer-review ClawSweeper verdict; this branch's useful helper-reuse idea can be folded there instead of keeping two landing candidates open. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Canonical path: Close this duplicate and concentrate review on #96360, optionally adopting this branch's So I’m closing this here and keeping the remaining discussion on #96360. Review detailsBest possible solution: Close this duplicate and concentrate review on #96360, optionally adopting this branch's Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main and Is this the best way to solve the issue? No. The helper reuse is a reasonable implementation detail, but the best solution is to use the canonical PR with focused tests and proof, folding this helper call into that branch only if maintainers prefer it. Security review: Security review cleared: The diff reuses an existing internal bounded JSON reader and does not change secrets, auth, dependencies, workflows, package resolution, or code execution surfaces. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 561c713bb1f3. |
|
ClawSweeper applied the proposed close for this PR.
|
|
Follow-up closeout: the landed replacement is #97659, merged as db2786b. Reason for replacement instead of editing this branch: maintainer push was rejected on the fork, and the original diff only covered the shared helper path; the landed replacement also bounds the MiniMax success path and Claude OAuth error-body parsing, with focused tests for both. Credit preserved from this PR in the replacement PR body. |
|
🦞👀 Reason: structured ClawSweeper close marker: close-required (sha=1f1c87e6fcbd4b59ff75176db959bd291da17e75) Usage: |
Summary
Replace unbounded
response.json()withreadProviderJsonResponsein thereadUsageJsonshared helper to cap provider usage API response bodies at 16 MiB. This prevents unbounded buffering of responses from all seven providers that call this helper: Claude, Gemini, Codex, Z.AI, DeepSeek, MiniMax, and OpenAI-compatible embeddings.Real behavior proof (required for external PRs)
Behavior addressed: Unbounded
response.json()replaced withreadProviderJsonResponse(16 MiB cap).Real environment tested: Linux, Node 22, OpenClaw main @ 87db23e
Exact steps or command run after fix:
Proof harness:
Evidence after fix:
The harness creates a streaming 64 MiB body with 1 MiB chunks. The bounded reader pulls only 17 chunks (stopping at the 16 MiB cap), cancels the stream, and returns the error snapshot. Before the fix,
response.json()would have buffered the entire 64 MiB before parsing.Observed result after fix:
readProviderJsonResponsecaps provider usage API responses at 16 MiB. Streaming bodies are cancelled at the cap instead of being fully buffered. The existing{ ok: false, snapshot }error contract is preserved for both overflow and malformed-JSON errors.All existing tests pass: 51 tests across 5 caller test files (claude, codex, deepseek, gemini, zai) plus the shared helpers test file.
What was not tested: Live provider usage API calls against Anthropic, Gemini, Codex, Z.AI, DeepSeek, or MiniMax usage endpoints were not tested.
Risk
Low. The 16 MiB cap matches the convention in
provider-http-errors.ts. The existing try-catch inreadUsageJsonpreserves the{ ok: false, snapshot }contract — overflow and JSON parse errors both return "Malformed usage response", matching the existing behavior for malformed-JSON responses.