Skip to content

fix(core): replace response.text with collectBoundedResponseBody for websearch SSE handling#33464

Closed
enioclimacosalesjunior wants to merge 2 commits into
anomalyco:devfrom
enioclimacosalesjunior:fix/websearch-400-error
Closed

fix(core): replace response.text with collectBoundedResponseBody for websearch SSE handling#33464
enioclimacosalesjunior wants to merge 2 commits into
anomalyco:devfrom
enioclimacosalesjunior:fix/websearch-400-error

Conversation

@enioclimacosalesjunior

Copy link
Copy Markdown

Problem

The built-in websearch tool returns HTTP 400 errors, reported by the model as "Tavily API error: 400 Bad Request". The root cause is that the websearch tool uses MCP endpoints (Exa/Parallel) that return Server-Sent Events (text/event-stream) responses. The v1.17.9 code reads the response body via response.text from Effect's HttpClientResponse, which can fail to properly decode SSE-formatted bodies.

The same issue exists in both packages:

  • packages/core/src/tool/websearch.ts (the core tool implementation)
  • packages/opencode/src/tool/mcp-websearch.ts (the opencode package MCP wrapper)

Analysis

When response.text is called on a text/event-stream response, the charset detection may behave incorrectly depending on the runtime and the Effect library version. The SSE response format (event: message\ndata: {...}\n\n) can cause decoding failures or produce malformed strings that the downstream parseResponse function cannot handle. The HttpClient.filterStatusOk correctly passes the 200 status, but the subsequent body decoding fails, resulting in a ToolFailure that the model interprets as a 400 error — even though the actual HTTP status is 200.

Fix

Replace response.text with collectBoundedResponseBody, which:

  1. Reads raw bytes from the response stream via response.stream
  2. Manually tracks sizes with upper bounds (MAX_RESPONSE_BYTES = 256 KB)
  3. Converts to UTF-8 explicitly with .toString("utf8")

This approach is already used by the webfetch tool (which has its own collectBody function) and was added upstream in this very commit 69f1ec22e ("fix(core): bound web tool failures").

Changes

Added

  • packages/core/src/tool/http-body.ts — Shared collectBoundedResponseBody function that reads a bounded response body from a stream, checks content-length headers, and returns a Buffer. This file was referenced by the import in websearch.ts but was missing from the v1.17.9 tag.

Modified

  • packages/core/src/tool/websearch.ts — Import and use collectBoundedResponseBody instead of response.text
  • packages/opencode/src/tool/mcp-websearch.ts — Same fix applied to the opencode package's MCP websearch wrapper

Testing

  • The existing test suite in packages/core/test/tool-websearch.test.ts covers provider selection, plain JSON and SSE response parsing, oversized body rejection, and API key isolation. All tests pass with this fix.
  • The fix matches the upstream commit 69f1ec22e on the dev branch.

Related

  • Upstream fix: commit 69f1ec22e ("fix(core): bound web tool failures")
  • Closes issue related to websearch returning 400 Bad Request for SSE-formatted responses

opencode and others added 2 commits June 21, 2026 00:02
…websearch to fix 400 error handling

response.text from Effect's HttpClientResponse can fail for SSE
responses (text/event-stream). Replace with collectBoundedResponseBody
which reads raw bytes from the stream, manually tracks size limits,
and converts to UTF-8 explicitly.

This matches the upstream fix in commit 69f1ec2 that was applied
after v1.17.9 but was missing from the tag.

Also fixes the same issue in packages/opencode/src/tool/mcp-websearch.ts
which had the same pattern.
@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Jun 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window.

Feel free to open a new pull request that follows our guidelines.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Jun 23, 2026
@github-actions github-actions Bot closed this Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant