anomalyco / anomalyco/opencode

Custom tool with `tool.schema.number()` argument crashes with "Cannot read properties of undefined (reading 'split')"

Open
#38,956 0 comments 0 reactions 1 assignee View on GitHub

@jlongster is already working on this.

Since Jul 26, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description
Description

Custom tools defined via @opencode-ai/plugin crash with Cannot read properties of undefined (reading 'split') when the tool's args schema includes a tool.schema.number() field and the LLM calls the tool with an argument for that field. Tools with no arguments work fine. Tools using only tool.schema.string() arguments also work fine — the crash is specific to the number type.

Environment
  • opencode version: 1.18.5 (macOS, darwin/fs-events backend)
  • @opencode-ai/plugin version: 1.18.5 (also reproduced on 1.18.4)
  • Reproduced with two different models/providers: deepseek-v4-flash-free and Gemini 3.5 — not model-specific.
  • Tool loaded from a project-local .opencode/tools/game.ts
Expected behavior

Tool executes and returns 9.

Actual behavior

Cannot read properties of undefined (reading 'split')

The agent then silently falls back to computing the sum itself in text, without surfacing the error clearly to the user (only a one-line inline error appears before the tool result).

Workaround found

Changing both args to tool.schema.string() and converting inside execute avoids the crash entirely:

export const add = tool({
  description: "Add two numbers",
  args: {
    a: tool.schema.string().describe("First number"),
    b: tool.schema.string().describe("Second number"),
  },
  async execute(args) {
    return String(Number(args.a) + Number(args.b))
  },
})

This strongly suggests the bug is in the Zod→JSON-Schema conversion path specific to the number type when serializing the tool schema for the model/provider, not in the model's tool-calling behavior itself (reproduced across two unrelated providers).

Additional notes
  • No matching stack trace appears in ~/.local/share/opencode/log/*.log — the error appears to be caught/displayed only in the session UI, not logged at ERROR level, which made this harder to trace. Might be worth logging the full stack trace for tool execution errors.
  • Happy to provide more detail or test a patch if useful.
Plugins

No response

OpenCode version

1.18.5

Steps to reproduce
  1. Create .opencode/tools/game.ts:
import { tool } from "@opencode-ai/plugin"

export default tool({
  description: "ping",
  args: {},
  async execute() { return "pong" },
})

export const add = tool({
  description: "Add two numbers",
  args: {
    a: tool.schema.number().describe("First number"),
    b: tool.schema.number().describe("Second number"),
  },
  async execute(args) {
    return args.a + args.b
  },
})
  1. Start opencode in the project directory, confirm the file loads (no Cannot find module errors, npm install completed successfully in .opencode).
  2. Prompt: "add 3 and 6" (triggers game_add).
Screenshot and/or share link

No response

Operating System

macOS 26.5.2

Terminal

No response

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.