MCP tools crash: TypeError on value.output.output in processor.ts (AI SDK 6.0.74 breaking change) #9016

Closed
opened 2026-02-16 18:11:24 -05:00 by yindo · 10 comments
Owner

Originally created by @kil-penguin on GitHub (Feb 10, 2026).

Originally assigned to: @rekram1-node on GitHub.

Bug Description

All MCP tool calls crash with:

TypeError: undefined is not an object (evaluating 'output.output.toLowerCase')

This affects every MCP tool (Slack, fetch, grep_app, etc.) — 100% reproducible.

Root Cause

AI SDK v6.0.74 (released Feb 6, 2026) introduced createToolModelOutput() in stream-text.ts (line 1270) which changed the tool-result output structure:

Before (what OpenCode expects):

value.output = {
  output: string,
  metadata: Record<string, any>,
  title: string,
  attachments?: FilePart[]
}

After (what AI SDK now returns):

value.output = {
  type: 'text' | 'json' | 'error-text' | 'error-json' | 'execution-denied' | 'content',
  value: string | JSONValue,
  providerOptions?: ProviderOptions
}

Crash Location

packages/opencode/src/session/processor.tstool-result case:

case "tool-result": {
  const match = toolcalls[value.toolCallId]
  if (match && match.state.status === "running") {
    await Session.updatePart({
      ...match,
      state: {
        status: "completed",
        input: value.input ?? match.state.input,
        output: value.output.output,       // ← undefined.toLowerCase() crashes here
        metadata: value.output.metadata,   // ← undefined
        title: value.output.title,         // ← undefined
        attachments: value.output.attachments,
      },
    })
  }
}

Full Data Flow

  1. MCP tool execute (mcp/index.tsconvertMcpTool()) returns MCP SDK CallToolResult: { content: [{type: "text", text: "..."}], isError? }
  2. AI SDK execute-tool-call.ts wraps it as { type: 'tool-result', output: <raw result> }
  3. AI SDK stream-text.ts (line 1270) now passes output through createToolModelOutput() → transforms to { type: 'text', value: '...' }
  4. OpenCode processor.ts tries to access .output, .metadata, .title on the new structure → crash

Why It Wasn't Caught

  • OpenCode's built-in tools return { output, title, metadata } from their execute functions
  • createToolModelOutput() wraps ALL tool outputs (including MCP) into the new ToolResultOutput shape
  • The processor was never updated to handle the new shape

Suggested Fix

Option A: Convert MCP result in mcp/index.ts (recommended)

// In convertMcpTool(), wrap the execute return:
execute: async (args: unknown) => {
  const result = await client.callTool(...)
  const textContent = result.content
    ?.filter((c: any) => c.type === "text")
    .map((c: any) => c.text)
    .join("\n") ?? ""
  return {
    output: textContent,
    title: mcpTool.name,
    metadata: {},
  }
},

Option B: Handle new output shape in processor.ts

case "tool-result": {
  const match = toolcalls[value.toolCallId]
  if (match && match.state.status === "running") {
    const raw = value.output ?? {}
    // Handle both old format { output, metadata, title } and new AI SDK format { type, value }
    const output = raw.output ?? raw.value ?? (typeof raw === "string" ? raw : JSON.stringify(raw))
    const metadata = raw.metadata ?? {}
    const title = raw.title ?? match.tool
    await Session.updatePart({
      ...match,
      state: {
        status: "completed",
        input: value.input ?? match.state.input,
        output,
        metadata,
        title,
        time: { start: match.state.time.start, end: Date.now() },
        attachments: raw.attachments,
      },
    })
  }
}

Environment

  • OpenCode: v1.1.56
  • AI SDK: 6.0.74 (from pnpm catalog)
  • @modelcontextprotocol/sdk: 1.25.2
  • OS: macOS (darwin)

Reproduction

  1. Configure any MCP server in opencode.json
  2. Call any MCP tool
  3. Crash occurs immediately on tool result processing
Originally created by @kil-penguin on GitHub (Feb 10, 2026). Originally assigned to: @rekram1-node on GitHub. ## Bug Description All MCP tool calls crash with: ``` TypeError: undefined is not an object (evaluating 'output.output.toLowerCase') ``` This affects **every** MCP tool (Slack, fetch, grep_app, etc.) — 100% reproducible. ## Root Cause AI SDK v6.0.74 (released Feb 6, 2026) introduced `createToolModelOutput()` in `stream-text.ts` (line 1270) which changed the tool-result output structure: **Before (what OpenCode expects):** ```typescript value.output = { output: string, metadata: Record<string, any>, title: string, attachments?: FilePart[] } ``` **After (what AI SDK now returns):** ```typescript value.output = { type: 'text' | 'json' | 'error-text' | 'error-json' | 'execution-denied' | 'content', value: string | JSONValue, providerOptions?: ProviderOptions } ``` ### Crash Location `packages/opencode/src/session/processor.ts` — `tool-result` case: ```typescript case "tool-result": { const match = toolcalls[value.toolCallId] if (match && match.state.status === "running") { await Session.updatePart({ ...match, state: { status: "completed", input: value.input ?? match.state.input, output: value.output.output, // ← undefined.toLowerCase() crashes here metadata: value.output.metadata, // ← undefined title: value.output.title, // ← undefined attachments: value.output.attachments, }, }) } } ``` ### Full Data Flow 1. **MCP tool execute** (`mcp/index.ts` → `convertMcpTool()`) returns MCP SDK `CallToolResult`: `{ content: [{type: "text", text: "..."}], isError? }` 2. **AI SDK `execute-tool-call.ts`** wraps it as `{ type: 'tool-result', output: <raw result> }` 3. **AI SDK `stream-text.ts`** (line 1270) now passes output through `createToolModelOutput()` → transforms to `{ type: 'text', value: '...' }` 4. **OpenCode `processor.ts`** tries to access `.output`, `.metadata`, `.title` on the new structure → crash ### Why It Wasn't Caught - OpenCode's built-in tools return `{ output, title, metadata }` from their execute functions - `createToolModelOutput()` wraps ALL tool outputs (including MCP) into the new `ToolResultOutput` shape - The processor was never updated to handle the new shape ## Suggested Fix ### Option A: Convert MCP result in `mcp/index.ts` (recommended) ```typescript // In convertMcpTool(), wrap the execute return: execute: async (args: unknown) => { const result = await client.callTool(...) const textContent = result.content ?.filter((c: any) => c.type === "text") .map((c: any) => c.text) .join("\n") ?? "" return { output: textContent, title: mcpTool.name, metadata: {}, } }, ``` ### Option B: Handle new output shape in `processor.ts` ```typescript case "tool-result": { const match = toolcalls[value.toolCallId] if (match && match.state.status === "running") { const raw = value.output ?? {} // Handle both old format { output, metadata, title } and new AI SDK format { type, value } const output = raw.output ?? raw.value ?? (typeof raw === "string" ? raw : JSON.stringify(raw)) const metadata = raw.metadata ?? {} const title = raw.title ?? match.tool await Session.updatePart({ ...match, state: { status: "completed", input: value.input ?? match.state.input, output, metadata, title, time: { start: match.state.time.start, end: Date.now() }, attachments: raw.attachments, }, }) } } ``` ## Environment - OpenCode: v1.1.56 - AI SDK: 6.0.74 (from pnpm catalog) - `@modelcontextprotocol/sdk`: 1.25.2 - OS: macOS (darwin) ## Reproduction 1. Configure any MCP server in opencode.json 2. Call any MCP tool 3. Crash occurs immediately on tool result processing
yindo closed this issue 2026-02-16 18:11:24 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Feb 10, 2026):


This issue appears to be a duplicate of #12987, which reports the identical error with MCP tools:

  • #12987: Kubernetes MCP server tools fail with TypeError: output.output.toLowerCase

Both issues report the same root cause: the AI SDK v6.0.74 breaking change in how tool output is structured. Your issue (#13042) provides more comprehensive root cause analysis and suggested fixes, which will be valuable for resolving both.

Please consider reviewing #12987 to see if the context there adds any additional details, and the issue assignee (rekram1-node) should be aware of both reports.

@github-actions[bot] commented on GitHub (Feb 10, 2026): --- This issue appears to be a duplicate of #12987, which reports the identical error with MCP tools: - **#12987**: Kubernetes MCP server tools fail with TypeError: output.output.toLowerCase Both issues report the same root cause: the AI SDK v6.0.74 breaking change in how tool output is structured. Your issue (#13042) provides more comprehensive root cause analysis and suggested fixes, which will be valuable for resolving both. Please consider reviewing #12987 to see if the context there adds any additional details, and the issue assignee (rekram1-node) should be aware of both reports.
Author
Owner

@ahmed-rezk-dev commented on GitHub (Feb 10, 2026):

I have the same issue

@ahmed-rezk-dev commented on GitHub (Feb 10, 2026): I have the same issue
Author
Owner

@vendys-sungwan commented on GitHub (Feb 10, 2026):

same + 1

@vendys-sungwan commented on GitHub (Feb 10, 2026): same + 1
Author
Owner

@Dis2017 commented on GitHub (Feb 10, 2026):

+1

@Dis2017 commented on GitHub (Feb 10, 2026): +1
Author
Owner

@nus-rick commented on GitHub (Feb 10, 2026):

+1

@nus-rick commented on GitHub (Feb 10, 2026): +1
Author
Owner

@Ctrl30 commented on GitHub (Feb 10, 2026):

+1

@Ctrl30 commented on GitHub (Feb 10, 2026): +1
Author
Owner

@My-Walker commented on GitHub (Feb 10, 2026):

+1

@My-Walker commented on GitHub (Feb 10, 2026): +1
Author
Owner

@ystgd07 commented on GitHub (Feb 10, 2026):

+1

@ystgd07 commented on GitHub (Feb 10, 2026): +1
Author
Owner

@rekram1-node commented on GitHub (Feb 10, 2026):

This is an oh my opencode bug not opencode

@rekram1-node commented on GitHub (Feb 10, 2026): This is an oh my opencode bug not opencode
Author
Owner

@ahmed-rezk-dev commented on GitHub (Feb 11, 2026):

This is an oh my opencode bug not opencode

You are correct. It did work after removing oh my opencode, Thank you :)

@ahmed-rezk-dev commented on GitHub (Feb 11, 2026): > This is an oh my opencode bug not opencode You are correct. It did work after removing oh my opencode, Thank you :)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#9016