Skip to content

fix(cli): bound docs search API response reads#98188

Merged
vincentkoc merged 1 commit into
openclaw:mainfrom
cxbAsDev:fix/bound-docs-search-response
Jun 30, 2026
Merged

fix(cli): bound docs search API response reads#98188
vincentkoc merged 1 commit into
openclaw:mainfrom
cxbAsDev:fix/bound-docs-search-response

Conversation

@cxbAsDev

Copy link
Copy Markdown
Contributor

What Problem This Solves

fetchDocsSearch in src/commands/docs.ts calls await response.json() on the docs.openclaw.ai search API response without a read limit. A large or malicious response could force the CLI to buffer arbitrarily large payloads before JSON parsing, risking OOM.

Supersedes #96251 — adds the committed regression test that ClawSweeper requested.

Why This Change Was Made

All external HTTP response reads should use readResponseWithLimit or readProviderJsonResponse to cap memory consumption. The docs search command already had a fetch timeout via AbortController but the response body was unbounded.

User Impact

The openclaw docs <query> command is now protected against oversized search API responses. Normal queries work identically. An oversized response produces a clear error message instead of buffering the entire body.

Evidence

Environment: Linux, Node 22, OpenClaw main

Committed tests pass (4/4, including oversized response rejection):

$ pnpm test src/commands/docs.test.ts --run --reporter=verbose

 ✓ docsSearchCommand > calls the Cloudflare docs search API
 ✓ docsSearchCommand > fails loudly when the Cloudflare docs search API fails
 ✓ docsSearchCommand > renders successful results from the Cloudflare docs search API
 ✓ docsSearchCommand > rejects oversized docs search responses

 Test Files  1 passed (1)
      Tests  4 passed (4)

Oversized response test proves the 8 MiB cap is enforced:

const stream = new ReadableStream<Uint8Array>({ cancel, start(controller) {
  for (let i = 0; i < 10; i++) controller.enqueue(new Uint8Array(ONE_MIB));
}});
// bounded reader throws "Docs search response exceeds 8388608 bytes"
// runtime.error called with the overflow message
// runtime.exit called with 1
// stream.cancel called once

Build succeeds (dist compiled, no type errors).

Risk

Low. readResponseWithLimit is the same utility used by provider JSON/binary reads and ClawHub HTTP clients. The 8 MiB cap is generous for a docs search API response. No config, auth, or API surface changes.

🤖 Generated with Claude Code

@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations size: XS labels Jun 30, 2026
@clawsweeper

clawsweeper Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 30, 2026, 12:55 PM ET / 16:55 UTC.

Summary
The PR updates the openclaw docs search command to read the docs API response with an 8 MiB readResponseWithLimit cap and adds an oversized-response regression test.

PR surface: Source +5, Tests +29. Total +34 across 2 files.

Reproducibility: yes. Current main and the latest release still call response.json() at the hosted docs search boundary, and the PR's 10 MiB stream test gives a high-confidence oversized-response path without needing a hostile live endpoint.

Review metrics: none identified.

Stored data model
Persistent data-model change detected: serialized state: src/commands/docs.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: canonical
Canonical: #98188
Summary: This PR is the current canonical attempt for the docs search bounded-read fix; the earlier same-author PR was closed unmerged after being superseded by this branch with committed overflow coverage.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Next step before merge

  • [P2] No repair lane is needed; the PR already contains the targeted code change and regression test, so the remaining action is ordinary maintainer and CI review.

Security
Cleared: The diff adds no dependency, workflow, secret, package, or new code-execution surface and narrows an existing resource-exhaustion risk with an internal bounded reader.

Review details

Best possible solution:

Land the focused bounded-read change after normal maintainer and required CI gates, preserving current CLI output for ordinary docs searches.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main and the latest release still call response.json() at the hosted docs search boundary, and the PR's 10 MiB stream test gives a high-confidence oversized-response path without needing a hostile live endpoint.

Is this the best way to solve the issue?

Yes. Reusing the existing media-core bounded reader at the docs search response boundary is the narrowest maintainable fix; the provider-specific JSON helper would add the wrong ownership label, and the command keeps its local parser/output behavior.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 6cb82eaab865.

Label changes

Label justifications:

  • P2: This is a normal-priority CLI resource-exhaustion hardening fix with a narrow openclaw docs blast radius and no urgent live regression evidence.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): Sufficient terminal proof: the linked superseded PR shows a real openclaw docs "installation guide" run after the same runtime change, and this PR adds committed overflow-path test evidence.
  • proof: sufficient: Contributor real behavior proof is sufficient. Sufficient terminal proof: the linked superseded PR shows a real openclaw docs "installation guide" run after the same runtime change, and this PR adds committed overflow-path test evidence.
Evidence reviewed

PR surface:

Source +5, Tests +29. Total +34 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 6 1 +5
Tests 1 29 0 +29
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 35 1 +34

What I checked:

  • Current main behavior: fetchDocsSearch still calls response.json() after a successful docs search response on current main, so the central unbounded-read problem remains unfixed there. (src/commands/docs.ts:78, 6cb82eaab865)
  • Latest release behavior: The latest release tag still has the same unbounded response.json() read in fetchDocsSearch, so this fix has not already shipped. (src/commands/docs.ts:78, e085fa1a3ffd)
  • PR implementation: The PR head imports readResponseWithLimit, sets an 8 MiB docs-search cap, throws a docs-specific overflow error, and parses only bounded bytes as JSON. (src/commands/docs.ts:80, b3eb3509abd7)
  • Regression coverage: The PR head adds a command-level test that feeds a 10 MiB response stream, expects the docs overflow error, exits with code 1, and verifies stream cancellation. (src/commands/docs.test.ts:98, b3eb3509abd7)
  • Bounded-reader contract: readResponseWithLimit reads a Response under a byte cap, cancels on overflow, and throws the caller-provided overflow error. (packages/media-core/src/read-response-with-limit.ts:130, 6cb82eaab865)
  • Docs command contract: The CLI docs page defines openclaw docs as calling the hosted search API and rendering JSON results with a fixed 30 second timeout; the PR preserves that surface while adding the response cap. Public docs: docs/cli/docs.md. (docs/cli/docs.md:38, 6cb82eaab865)

Likely related people:

  • pick-cat: Current-main blame for fetchDocsSearch, docsSearchCommand registration, tests, and readResponseWithLimit points to the same recent command-area commit. (role: recent area contributor; confidence: medium; commits: eb5fb2aa69f4; files: src/commands/docs.ts, src/commands/docs.test.ts, src/cli/docs-cli.ts)
  • steipete: GitHub path history shows steipete introduced the Cloudflare docs search API path and later touched the media-core extraction/package surface used by the fix. (role: feature-history owner; confidence: high; commits: 69d84d775b63, 77f1359612f6, de1dfab03ef0; files: src/commands/docs.ts, src/commands/docs.test.ts, packages/media-core/src/read-response-with-limit.ts)
  • hclsys: GitHub path history shows hclsys added or repaired adjacent docs command test coverage and touched the same docs CLI surface. (role: recent adjacent contributor; confidence: medium; commits: c421be6c9025; files: src/commands/docs.ts, src/commands/docs.test.ts, docs/cli/docs.md)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. labels Jun 30, 2026
@vincentkoc
vincentkoc force-pushed the fix/bound-docs-search-response branch from 560861d to b3eb350 Compare June 30, 2026 16:48
@vincentkoc
vincentkoc merged commit f284ce3 into openclaw:main Jun 30, 2026
94 checks passed
@vincentkoc

Copy link
Copy Markdown
Member

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 1, 2026
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 1, 2026
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 3, 2026
Rorqualx pushed a commit to Rorqualx/cortex that referenced this pull request Jul 6, 2026
Rorqualx pushed a commit to Rorqualx/cortex that referenced this pull request Jul 8, 2026
@cxbAsDev
cxbAsDev deleted the fix/bound-docs-search-response branch July 15, 2026 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands Command implementations P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XS status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants