Skip to content

fix(core): report MCP web search tool errors instead of empty results - #56700

Closed
fihaaade wants to merge 1 commit into
anomalyco:devfrom
fihaaade:websearch-mcp-error
Closed

fihaaade wants to merge 1 commit into
anomalyco:devfrom
fihaaade:websearch-mcp-error

Conversation

@fihaaade

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #54311 (the empty-results part; see below for what this leaves open)

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

MCP search endpoints report tool failures as a 200 response whose result has isError: true. Firecrawl and Exa do this when their keyless quota runs out, with a message like "You've hit Firecrawl's free MCP rate limit" (traced by @carson2222 in #54311). WebSearchMcp.call ignored the flag. The adapter couldn't decode the message as results and returned [], so the tool said "No search results found. Please try a different query." and the model had no idea why.

WebSearchMcp.call now fails with a WebSearchMcp.ToolError that carries the provider's text when isError is set. This covers every MCP-based provider (Exa, Parallel, Firecrawl, TinyFish). The websearch tool shows it as Web search failed: <provider message>. Valid responses are unchanged.

Not included: with websearch.provider: "random", opencode still only switches providers on HTTP 429, so this error doesn't rotate to another provider. Rotating on it would change retry behavior, and I'm happy to follow up if you want that. The keyless-docs part of #54311 is also not covered here.

How did you verify your code works?

  • test/plugin/websearch.test.ts: for each MCP provider, a 200 response with isError: true now fails with ToolError and the provider's message. These fail on dev, where the query succeeds with no results.
  • test/tool-websearch.test.ts: the tool error message is Web search failed: <provider message>. It fails without the tool change.
  • All websearch tests in packages/core (60) and bun typecheck in packages/core pass.

Screenshots / recordings

N/A

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

🤖 Generated with Claude Code

MCP search endpoints report tool failures, such as an exhausted keyless
quota, as a 200 response with isError. WebSearchMcp.call ignored the flag,
so the provider's message was lost and the search reported "No search
results found". Fail with the provider's message instead, and show it in
the websearch tool error.

Refs anomalyco#54311

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@opencode-agent opencode-agent Bot closed this Oct 18, 2026
@opencode-agent

Copy link
Copy Markdown
Contributor

Thanks for tracking this down and for the clear write-up and tests!

I think this duplicates #50938, which is still open. It also makes MCP isError results (and JSON-RPC errors) fail with the provider's own message instead of returning "No search results found", and it uses the same Firecrawl free-tier rate-limit example. It covers the other providers as well (Tavily, OpenCode Web Search) and the response-size limits.

If you see something missing there, such as a provider case or a test like the ones you wrote here, a review, testing or a comment on #50938 would be very welcome. The random provider fallback part of #54311 isn't covered by either pull request, so that could still be its own focused change.

@fihaaade

Copy link
Copy Markdown
Contributor Author

#50938 was closed by the automated cleanup on 2026-10-23 without being merged, so the empty-results problem in #54311 is still unfixed on dev. Could a maintainer reopen this PR, or let me know if you'd prefer another approach? I'd also like to follow up with the random provider fallback from #54311 on top of it.

@JuampiHernandez

Copy link
Copy Markdown

Hey, I'm Juampi from the Firecrawl team.

Adding a Firecrawl-side data point in support of the reopen request above. In tests on Oct 25 and again today (Oct 26) with no Authorization header, firecrawl_search on https://mcp.firecrawl.dev/v2/mcp returns HTTP 200 with a tool error:

{"result":{"content":[{"type":"text","text":"Anonymous keyless access is unavailable for this request.\n\nFix: Create an API key at https://firecrawl.dev/... and then:\n- Set the header: Authorization: Bearer YOUR_API_KEY ..."}],"isError":true}}

On current dev (1743d1a), opencode api post /api/websearch --data '{"query":"latest Bun release"}' with websearch.provider: "firecrawl" and no key returns {"providerID":"firecrawl","results":[]}, so the user sees "No search results found" instead of that message. With FIRECRAWL_API_KEY set, the same call returns results. Surfacing isError as this PR does would show the user the fix. It doesn't change the random fallback from #54311.

@fihaaade

Copy link
Copy Markdown
Contributor Author

Reopened as #59637, rebased on current dev. Thanks @JuampiHernandez for confirming the Firecrawl response.

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.

websearch: V2 keyless search is undocumented and "random" can stick to a failing provider

2 participants