[Bug]: NoSuchToolError (dummy_tool) should be gracefully handled instead of crashing the session #9168

Open
opened 2026-02-16 18:11:48 -05:00 by yindo · 1 comment
Owner

Originally created by @zrt-ai-lab on GitHub (Feb 12, 2026).

Originally assigned to: @rekram1-node on GitHub.

Description

When the model hallucinates a tool call to a non-existent tool during compaction or agent recovery, OpenCode throws a NoSuchToolError (displayed as dummy_tool) and crashes the agent turn. This makes the session unrecoverable.

Error message:

⚙ dummy_tool Model tried to call unavailable tool 'invalid'. Available tools: .

Root Cause

The AI SDK's tool execution layer throws NoSuchToolError when a model generates a tool call for a tool name that doesn't exist in the current tool registry. This error is not caught and gracefully handled — it propagates up and terminates the agent turn.

This commonly happens when:

  1. Compaction agent (which has no tools) receives a model response containing tool calls
  2. Sub-agents with limited tool sets receive hallucinated tool calls after being interrupted/resumed
  3. Custom providers that don't return usage data cause incorrect context window estimation, leading to overflow and confused model behavior

Proposed Fix

Instead of throwing a fatal error, OpenCode should gracefully handle unknown tool calls:

// In the tool execution layer:
try {
  const result = await executeTool(toolCall);
} catch (error) {
  if (error instanceof NoSuchToolError) {
    // Log warning but don't crash
    log.warn(`Model hallucinated tool call to '${error.toolName}', skipping`);
    // Return an error result to the model so it can self-correct
    return {
      type: "tool-result",
      toolCallId: toolCall.toolCallId,
      result: `Error: Tool '${error.toolName}' does not exist. Please use only available tools.`,
      isError: true,
    };
  }
  throw error;
}

This approach:

  • Doesn't crash the session
  • Informs the model that the tool doesn't exist (self-correction opportunity)
  • Preserves the message history for debugging
  • Is consistent with how other errors (e.g., tool execution failures) are already handled

Steps to Reproduce

  1. Use a custom OpenAI-compatible provider that doesn't return usage in streaming responses
  2. Have a long coding session with tool calls
  3. When context overflows, compaction triggers
  4. The compaction agent (no tools available) sometimes receives a model response with hallucinated tool calls
  5. dummy_tool error terminates the session

Expected Behavior

OpenCode should return a tool error result to the model and allow the conversation to continue, rather than crashing the entire agent turn.

Actual Behavior

Fatal NoSuchToolError is thrown, displayed as dummy_tool, session becomes unrecoverable.

Impact

  • Session becomes permanently stuck
  • User must start a new session, losing all context
  • Especially problematic with custom/proxy providers that lack usage data
  • Worsened by plugins that add sub-agents (e.g., oh-my-opencode's Sisyphus)

Environment

  • OpenCode version: 1.1.60
  • OS: macOS (arm64)
  • Provider: Custom OpenAI-compatible (API proxy, no usage in responses)
  • Plugin: oh-my-opencode 3.5.2

Related Issues

  • #13141 — Custom provider missing usage → compaction timing issues
  • #13033 — Compaction UX improvements
  • #11722 — Skill/tool not found errors
  • #13214 — Compaction check logic fix (merged)
Originally created by @zrt-ai-lab on GitHub (Feb 12, 2026). Originally assigned to: @rekram1-node on GitHub. ### Description When the model hallucinates a tool call to a non-existent tool during compaction or agent recovery, OpenCode throws a `NoSuchToolError` (displayed as `dummy_tool`) and crashes the agent turn. This makes the session unrecoverable. **Error message:** ``` ⚙ dummy_tool Model tried to call unavailable tool 'invalid'. Available tools: . ``` ### Root Cause The AI SDK's tool execution layer throws `NoSuchToolError` when a model generates a tool call for a tool name that doesn't exist in the current tool registry. This error is not caught and gracefully handled — it propagates up and terminates the agent turn. This commonly happens when: 1. **Compaction agent** (which has no tools) receives a model response containing tool calls 2. **Sub-agents** with limited tool sets receive hallucinated tool calls after being interrupted/resumed 3. **Custom providers** that don't return `usage` data cause incorrect context window estimation, leading to overflow and confused model behavior ### Proposed Fix Instead of throwing a fatal error, OpenCode should **gracefully handle** unknown tool calls: ```typescript // In the tool execution layer: try { const result = await executeTool(toolCall); } catch (error) { if (error instanceof NoSuchToolError) { // Log warning but don't crash log.warn(`Model hallucinated tool call to '${error.toolName}', skipping`); // Return an error result to the model so it can self-correct return { type: "tool-result", toolCallId: toolCall.toolCallId, result: `Error: Tool '${error.toolName}' does not exist. Please use only available tools.`, isError: true, }; } throw error; } ``` This approach: - Doesn't crash the session - Informs the model that the tool doesn't exist (self-correction opportunity) - Preserves the message history for debugging - Is consistent with how other errors (e.g., tool execution failures) are already handled ### Steps to Reproduce 1. Use a custom OpenAI-compatible provider that doesn't return `usage` in streaming responses 2. Have a long coding session with tool calls 3. When context overflows, compaction triggers 4. The compaction agent (no tools available) sometimes receives a model response with hallucinated tool calls 5. `dummy_tool` error terminates the session ### Expected Behavior OpenCode should return a tool error result to the model and allow the conversation to continue, rather than crashing the entire agent turn. ### Actual Behavior Fatal `NoSuchToolError` is thrown, displayed as `dummy_tool`, session becomes unrecoverable. ### Impact - Session becomes permanently stuck - User must start a new session, losing all context - Especially problematic with custom/proxy providers that lack `usage` data - Worsened by plugins that add sub-agents (e.g., oh-my-opencode's Sisyphus) ### Environment - **OpenCode version**: 1.1.60 - **OS**: macOS (arm64) - **Provider**: Custom OpenAI-compatible (API proxy, no `usage` in responses) - **Plugin**: oh-my-opencode 3.5.2 ### Related Issues - #13141 — Custom provider missing usage → compaction timing issues - #13033 — Compaction UX improvements - #11722 — Skill/tool not found errors - #13214 — Compaction check logic fix (merged)
Author
Owner

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

This issue addresses an important principle similar to #8009: tool errors should be gracefully returned to the agent rather than crashing the session. While #8009 focuses on GitHub Actions, this issue extends that principle to NoSuchToolError handling in the core tool execution layer.

The proposed fix is well-reasoned and consistent with error handling patterns already used elsewhere in OpenCode.

@github-actions[bot] commented on GitHub (Feb 12, 2026): This issue addresses an important principle similar to #8009: tool errors should be gracefully returned to the agent rather than crashing the session. While #8009 focuses on GitHub Actions, this issue extends that principle to NoSuchToolError handling in the core tool execution layer. The proposed fix is well-reasoned and consistent with error handling patterns already used elsewhere in OpenCode.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#9168