CLAUDE LABJP
FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as OctoberFORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Articles/API & SDK
API & SDK/2026-05-17Intermediate

Claude SDK Tool Calls Failing with InputValidationError: How to Handle Deferred Tools

When Claude Code SDK or Cowork tools throw InputValidationError, the root cause is usually deferred tool schemas. This guide explains why it happens and how to fix it with ToolSearch.

Claude SDKInputValidationErrorDeferred ToolsToolSearchAPI27Troubleshooting11

If you've been building agents with the Claude SDK, you may have run into this:

InputValidationError: Tool not found or schema not loaded

The tool name is correct. The code looks fine. But the call keeps failing. I'm Masaki Hirokawa — an independent developer who has shipped apps with over 50 million cumulative downloads, including Beautiful HD Wallpapers for iOS and Android. I build most of my automation tooling on the Claude SDK, and this specific error tripped me up more than once while setting up the content pipeline behind Dolice Labs.

The fix is straightforward once you understand what deferred tools are — but the documentation is easy to skim over without the concept clicking. Here's what's actually happening and how to resolve it.

Why InputValidationError Happens

The Claude SDK — and higher-level implementations like Cowork — uses a deferred tools mechanism. Rather than loading every tool's full JSON Schema into the context window at startup, it defers loading until the tool is actually needed.

When a tool is in the deferred state, the agent knows the tool's name but not its parameter schema (required fields, types, validation constraints). If you call a deferred tool directly, the SDK has no schema to validate your inputs against and throws InputValidationError.

// ❌ This fails when the schema hasn't been loaded
const result = await callTool("WebSearch", { query: "Claude API changelog" });
// → InputValidationError: schema not loaded for 'WebSearch'

The reason for this design is practical: tool sets — especially those extended via MCP plugins — vary by session. Loading every schema upfront would bloat the context window. Deferred loading means only the schemas you actually use get loaded.

Fix: Load the Schema with ToolSearch First

The solution is to call ToolSearch before calling the tool. This fetches the full schema and makes the tool callable.

// ✅ Correct order
 
// Step 1: fetch the schema
await ToolSearch({ query: "select:WebSearch" });
 
// Step 2: now the tool is safe to call
const result = await WebSearch({ query: "Claude API changelog" });

ToolSearch supports two query formats:

Direct selection (most reliable):

await ToolSearch({ query: "select:WebSearch,TaskCreate,TaskUpdate" })

Keyword search:

await ToolSearch({ query: "bash shell execute" })

When you need multiple tools, use select: with comma-separated names to resolve all of them in a single call. Keyword search is useful when you don't know the exact name, but direct selection is more predictable.

Identifying Deferred Tools

In Cowork (which runs on the Claude Agent SDK), the session system prompt includes a <system-reminder> block that lists all deferred tools at startup:

The following deferred tools are now available via ToolSearch.
Their schemas are NOT loaded — calling them directly will fail with InputValidationError.
Use ToolSearch with query "select:<name>[,<name>...]" to load tool schemas before calling them:

TaskCreate
TaskGet
WebSearch
mcp__workspace__bash
mcp__4cebb999__generate-design
...

If you see this reminder, run ToolSearch before calling any tool on the list.

Step-by-Step Debugging

Here's the exact process I use when an agent starts throwing InputValidationError in one of my scheduled tasks:

Step 1: Read the full error message

InputValidationError: Tool 'mcp__workspace__bash' parameters validation failed

If the error mentions a specific tool name and includes "schema not loaded" or "validation failed," deferred tools are almost certainly the issue. Distinguish this from ToolNotFoundError, which means the tool simply doesn't exist — a different problem with a different fix.

Step 2: Check the system-reminder

Scan the conversation log for the <system-reminder> block and confirm that the tool you're trying to call appears in the deferred list.

Step 3: Load the schema, then retry

// Load the schema first
await ToolSearch({ query: "select:mcp__workspace__bash" });
 
// Now call the tool
const output = await mcp__workspace__bash({ command: "ls /tmp" });

In the vast majority of cases, this resolves the issue immediately.

Common Mistake Patterns

Pattern 1: Assuming schemas persist across sessions

A deferred tool that worked in a previous session returns to the deferred state when a new session starts. Scheduled tasks that spin up a fresh session each run are the most common place this bites you.

// ❌ Worked yesterday, failing now — because it's a new session
const result = await mcp__workspace__bash({ command: "echo hello" });
// ✅ Load at session start, every session
await ToolSearch({ query: "select:mcp__workspace__bash,TaskCreate,TaskUpdate" });
// Safe to call from here on

Pattern 2: Calling a newly-installed plugin immediately

Newly installed MCP servers and plugins start in the deferred state. The most common version of this: you install the Canva or Figma plugin, try to call one of its tools right away, and get InputValidationError. The fix is always the same — run ToolSearch first.

Pattern 3: Not awaiting ToolSearch

// ❌ Fire and forget — schema may not be ready on the next line
ToolSearch({ query: "select:WebSearch" });
WebSearch({ query: "..." });  // Schema may still be deferred
// ✅ Always await ToolSearch before calling the tool
await ToolSearch({ query: "select:WebSearch" });
const result = await WebSearch({ query: "..." });

Pattern 4: Changing parameters instead of loading the schema

InputValidationError sounds like a problem with your input values, which leads some developers to iterate on parameters rather than fixing the schema load. If the error message includes "schema not loaded" rather than specific field validation failures, the parameters themselves are not the issue.

Production Pattern: Load at Session Start

My automated publishing system generates daily articles across four sites. Each scheduled task runs in a new session, so I load all required tool schemas as the very first step of every task.

// Always the first thing a scheduled task does
async function initializeTools() {
  await ToolSearch({
    query: "select:mcp__workspace__bash,TaskCreate,TaskUpdate,WebSearch"
  });
}
 
async function runDailyTask() {
  await initializeTools();
 
  // All tools are now safe to call
  const wsResult = await mcp__workspace__bash({
    command: 'ls -d /sessions/*/mnt/Workspace 2>/dev/null | head -1'
  });
 
  const ws = wsResult.stdout.trim();
  // ... rest of task
}

Since adopting this pattern, I haven't had a single task fail due to deferred tool errors. The ToolSearch call itself takes only a few hundred milliseconds — negligible against the total task runtime.

MCP Plugin Tools

Tools from MCP plugins like Canva, Figma, or Slack follow a naming pattern of mcp__{uuid}__{tool-name}, which makes them harder to reference directly.

// Full name approach
await ToolSearch({
  query: "select:mcp__4cebb999-208a-460c-96cf-29ee38abf5d6__generate-design"
});

When the UUID feels unwieldy, keyword search works too:

// Keyword approach
await ToolSearch({ query: "canva generate design" });

Looking back

When a tool call throws InputValidationError, check for deferred tools before assuming anything is wrong with your inputs:

  1. Check the <system-reminder> deferred tools list for your tool's name
  2. Call await ToolSearch({ query: "select:ToolName" }) to load the schema
  3. Confirm the await completes before calling the tool

For scheduled tasks and automation pipelines that start a new session each run, load all schemas upfront at session start. It's a small, reliable pattern that eliminates this entire class of errors.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

API & SDK2026-07-14
A Two-Stage Pre-Publish Gate for User-Facing AI Text in Consumer Apps
Design a two-stage pre-publish gate for short AI-generated text you ship to end users: a deterministic rule layer plus a Claude classifier, with fail-closed handling, generation-time vetting, and a cost model. Full implementation code included.
API & SDK2026-07-12
A Long Non-Streaming Response Was Billed Twice Past the 10-Minute Wall: Redesigning the SDK's Default Timeout and Retries
The Anthropic SDK's default 10-minute timeout and two automatic retries can silently re-run a long non-streaming response and bill you twice. Here is how the trap works, and how to close it with streaming, explicit timeout/max_retries, and a small local ledger — with measured before/after numbers.
API & SDK2026-06-22
Drop Your Static Claude API Keys: Moving CI and Production to Keyless Auth with Workload Identity Federation
Workload Identity Federation is now generally available on the Claude Platform. This guide walks through replacing long-lived sk-ant- keys with short-lived OIDC tokens, including keyless GitHub Actions auth, the migration steps, and token refresh design.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →