anomalyco / anomalyco/opencode
MCP: tool error responses crash with 'undefined is not an object (evaluating output.includes)' instead of surfacing the server error
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
When an MCP tool call returns an error (e.g. HTTP 401 from the server), the tool result is not the server's error — it is a wrapper crash:
undefined is not an object (evaluating 'output.includes')
The original error (status code, server message) is lost. Any MCP server that rejects a request makes every affected tool in the session report this JS TypeError instead of the real failure.
Environment
- opencode
1.18.31 - Windows 11, PowerShell 7.6.6
- Node v22.22.0
- HTTP (streamable) MCP servers, OAuth
Repro
- Configure any HTTP MCP server whose requests will be rejected (expired/missing OAuth token → 401, or any 4xx).
- Call any tool on that server.
- The tool result is
undefined is not an object (evaluating 'output.includes')instead of the 401/error payload.
Observed across multiple independent servers in one session (a 401 from an identity provider MCP relay, and a 401 from a knowledge-base MCP relay), so it is the shared error path, not one server's payload shape.
Expected
The tool result surfaces the MCP protocol error (error text / isError result / status code) so the caller and the model can see what the server actually returned.
Actual
The wrapper's error-handling path dereferences output without a null check (output.includes(...)) — output is undefined on the error branch — and that TypeError replaces the server's error.
Impact
- Auth failures (401) are indistinguishable from any other wrapper bug, which makes diagnosing MCP authentication impossible from inside a session.
- Affected tools appear "broken" when the real problem is an expired token or wrong URL.
Suggested fix
Guard the error branch: if output is null/undefined, surface a stable message (e.g. "MCP tool call failed with — no body returned") instead of calling .includes on it.
Notes
- Unrelated to the
SystemPrompt.environment/a.namecrash family (e.g. #49158, #48811) — different expression, different code path. - A separate symptom was observed in the same environment: after a 1-hour access token in
~/.local/share/opencode/mcp-auth.jsonexpired, calls failed 401 despite a validrefreshTokenbeing stored — the refresh does not appear to run automatically. Happy to open that as a separate issue if it reproduces for you.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Locate the shared MCP tool error-handling path containing output.includes, then reproduce the failure with an HTTP MCP server returning a 401 or other 4xx response. Trace the undefined error branch and add coverage for rejected tool calls; done means the MCP error text, status, or isError result reaches the caller instead of the wrapper TypeError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100