anomalyco / anomalyco/opencode

MCP: tool error responses crash with 'undefined is not an object (evaluating output.includes)' instead of surfacing the server error

Open
#49,892 0 comments 0 reactions 0 assignees View on GitHub

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

  1. Configure any HTTP MCP server whose requests will be rejected (expired/missing OAuth token → 401, or any 4xx).
  2. Call any tool on that server.
  3. 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.name crash 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.json expired, calls failed 401 despite a valid refreshToken being stored — the refresh does not appear to run automatically. Happy to open that as a separate issue if it reproduces for you.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.