fix(providers): bound successful OAuth and webhook responses#98098
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 2, 2026, 9:35 PM ET / 01:35 UTC. Summary PR surface: Source +15. Total +15 across 3 files. Reproducibility: yes. Current main has unbounded response.text()/response.json() reads in the touched success and error paths, and the PR body provides after-fix loopback terminal output for normal, oversized, malformed, and 204 cases; I did not run tests locally because this review is read-only. Review metrics: 2 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land one canonical bounded-read implementation for these exact paths, keeping the shared SDK readers and Discord 204 guard while coordinating merge order with the overlapping bounded-read PRs. Do we have a high-confidence way to reproduce the issue? Yes. Current main has unbounded response.text()/response.json() reads in the touched success and error paths, and the PR body provides after-fix loopback terminal output for normal, oversized, malformed, and 204 cases; I did not run tests locally because this review is read-only. Is this the best way to solve the issue? Yes. Reusing readProviderJsonResponse/readResponseTextLimited at the plugin-owned call sites is the narrowest maintainable fix; custom per-provider readers or continued parse fallbacks would duplicate the SDK contract or weaken explicit overflow signaling. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 4440226d52c2. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +15. Total +15 across 3 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
|
|
Hi maintainers 👋 Could a maintainer please Approve and run the pending workflows? The key checks should pass. Thanks! |
fea9a02 to
60292e2
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Fixed OpenRouter OAuth: replaced @clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Addressed ClawSweeper findings:
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Updated PR body with comprehensive real behavior proof following the same pattern as PR #98260:
@clawsweeper re-review |
|
Restructured PR body with proper @clawsweeper re-review |
|
Fixed Discord 204 No Content regression:
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Added loopback proof with local HTTP server simulating real API responses for all 6 scenarios:
@clawsweeper re-review |
|
@clawsweeper re-review |
Co-authored-by: WenyuanLee <[email protected]>
fbbab0d to
2b747ee
Compare
|
Merged via squash.
|
…w#98098) Co-authored-by: Peter Steinberger <[email protected]>
…mantics The thread-ownership 409 conflict path still used unbounded resp.json(), inconsistent with the bounded readers shipped across the other channel/provider success paths. A compromised or buggy forwarder returning a multi-GB 409 body would buffer the entire body before JSON.parse, OOMing the agent. Bound the 409 body via readResponseTextLimited (8 KiB cap; a 409 owner field is ~30 bytes). Wrap the parse in try/catch so a truncated or malformed 409 body still cancels the send (owner logged as "unknown") — the 409 status itself means another agent owns this thread, independent of body parseability. The discord webhook and huggingface /v1/models success reads from the original PR were superseded upstream by openclaw#98098 and openclaw#101079 (readProviderJsonResponse), so this branch now carries only the thread-ownership fix. Co-Authored-By: Claude <[email protected]>
…w#98098) Co-authored-by: Peter Steinberger <[email protected]>
…mantics The thread-ownership 409 conflict path still used unbounded resp.json(), inconsistent with the bounded readers shipped across the other channel/provider success paths. A compromised or buggy forwarder returning a multi-GB 409 body would buffer the entire body before JSON.parse, OOMing the agent. Bound the 409 body via readResponseTextLimited (8 KiB cap; a 409 owner field is ~30 bytes). Wrap the parse in try/catch so a truncated or malformed 409 body still cancels the send (owner logged as "unknown") — the 409 status itself means another agent owns this thread, independent of body parseability. The discord webhook and huggingface /v1/models success reads from the original PR were superseded upstream by openclaw#98098 and openclaw#101079 (readProviderJsonResponse), so this branch now carries only the thread-ownership fix. Co-Authored-By: Claude <[email protected]>
…mantics (#98941) * fix(thread-ownership): bound 409 response read and preserve cancel semantics The thread-ownership 409 conflict path still used unbounded resp.json(), inconsistent with the bounded readers shipped across the other channel/provider success paths. A compromised or buggy forwarder returning a multi-GB 409 body would buffer the entire body before JSON.parse, OOMing the agent. Bound the 409 body via readResponseTextLimited (8 KiB cap; a 409 owner field is ~30 bytes). Wrap the parse in try/catch so a truncated or malformed 409 body still cancels the send (owner logged as "unknown") — the 409 status itself means another agent owns this thread, independent of body parseability. The discord webhook and huggingface /v1/models success reads from the original PR were superseded upstream by #98098 and #101079 (readProviderJsonResponse), so this branch now carries only the thread-ownership fix. Co-Authored-By: Claude <[email protected]> * fix(thread-ownership): bound forwarder conflict handling --------- Co-authored-by: Claude <[email protected]>
…mantics (openclaw#98941) * fix(thread-ownership): bound 409 response read and preserve cancel semantics The thread-ownership 409 conflict path still used unbounded resp.json(), inconsistent with the bounded readers shipped across the other channel/provider success paths. A compromised or buggy forwarder returning a multi-GB 409 body would buffer the entire body before JSON.parse, OOMing the agent. Bound the 409 body via readResponseTextLimited (8 KiB cap; a 409 owner field is ~30 bytes). Wrap the parse in try/catch so a truncated or malformed 409 body still cancels the send (owner logged as "unknown") — the 409 status itself means another agent owns this thread, independent of body parseability. The discord webhook and huggingface /v1/models success reads from the original PR were superseded upstream by openclaw#98098 and openclaw#101079 (readProviderJsonResponse), so this branch now carries only the thread-ownership fix. Co-Authored-By: Claude <[email protected]> * fix(thread-ownership): bound forwarder conflict handling --------- Co-authored-by: Claude <[email protected]>
What Problem This Solves
Caps successful JSON response bodies in the two provider-controlled paths that were still unbounded on current
main:The original Google path was removed because
fetchWithTimeoutalready applies the same 16 MiB response cap. The proposed Nextcloud path was also already fixed onmain.Why This Change Was Made
Both remaining paths now use the shared
readProviderJsonResponsehelper, which rejects and cancels oversized streams. Discord keeps its existing transport contract:wait=false204 responses require no body, and malformed or oversized optional bodies after a successful non-idempotent POST do not turn the completed send into an error that could trigger a duplicate bot fallback.User Impact
Evidence
Closes no issue.