Claude SDK を使ってエージェントを開発していると、こんなエラーに突然ぶつかることがあります。
InputValidationError: Tool not found or schema not loaded
ツール名は正しい、コードも問題なさそうに見える。なのにエラーが返ってくる。私は廣川政樹というアプリ開発者兼アーティストで、Beautiful HD Wallpapers(iOS/Android、累計 5,000 万 DL 超)を始めとする複数のアプリを個人で運営しながら、Claude SDK ベースのコンテンツ自動化パイプラインを4サイト分構築しています。この InputValidationError には、その構築過程で何度か直面しました。
原因を理解してしまえば単純なのですが、ドキュメントには「deferred tools」という概念がさらっとしか書かれておらず、最初は何が起きているのか分かりませんでした。同じところで詰まっている方のために、根本原因と解決策を整理します。
なぜ InputValidationError が起きるのか
Claude SDK(および Cowork などの上位実装)には、deferred toolsと呼ばれる仕組みがあります。これはすべてのツールスキーマを最初からコンテキストに読み込まず、必要になったときだけ解決する遅延ロード方式です。
ツールが deferred 状態のとき、エージェントはそのツールの名前は知っています。しかしパラメータのスキーマ(入力の型・必須フィールドなど)はまだ読み込まれていません。
この状態でツールを直接呼び出そうとすると、SDK は「スキーマがないから呼べない」と判断し、InputValidationError を投げます。
// ❌ こうすると失敗する(スキーマがロードされていない状態)
const result = await callTool("WebSearch", { query: "Claude API changelog" });
// → InputValidationError: schema not loaded for 'WebSearch'
なぜこのような設計になっているかというと、利用可能なツール群(特に MCP プラグイン経由で追加されるもの)はセッションごとに異なる可能性があり、すべてのスキーマを最初から読み込むとコンテキストウィンドウを圧迫するからです。遅延ロードにより、実際に使うツールのスキーマだけをロードできます。
ToolSearch でスキーマを先にロードする
解決策は明快です。ツールを呼び出す前に ToolSearch でスキーマを取得することです。
// ✅ 正しい順序
// Step 1: スキーマを取得する
await ToolSearch({ query: "select:WebSearch" });
// Step 2: スキーマが返ってきてからツールを呼び出す
const result = await WebSearch({ query: "Claude API changelog" });ToolSearch のクエリには2つの形式があります。
1. 名前指定(最も確実):
await ToolSearch({ query: "select:WebSearch,TaskCreate,TaskUpdate" })2. キーワード検索:
await ToolSearch({ query: "bash shell execute" })複数のツールスキーマを一度に取得したいときは、select: 形式でカンマ区切りにします。キーワード検索は名前が分からないときに便利ですが、意図しないツールがマッチすることがあるため、名前が分かっているなら select: を使う方が確実です。
どのツールが Deferred になるのか
Cowork(Claude Code SDK ベース)では、セッション開始時にシステムプロンプトの <system-reminder> 内に deferred tools のリストが表示されます。ここに名前が並んでいるツールはスキーマ未ロードです。
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
...
このメッセージが出ていたら、必ず ToolSearch を先に実行してからツールを呼び出してください。
実際のデバッグ手順
私が Dolice Labs のスケジュールタスクで遭遇したケースを例に、実際のデバッグ手順を紹介します。4サイトそれぞれで1日4本の記事を自動生成するパイプラインを組んでいて、深夜〜早朝に走るスケジュールタスクがこのエラーで止まっていました。
Step 1: エラーメッセージを確認する
InputValidationError: Tool 'mcp__workspace__bash' parameters validation failed
InputValidationError かつツール名が含まれている場合は、deferred tools 問題の可能性が高いです。ToolNotFoundError(ツール自体が存在しない)とは区別してください。後者は別の問題です。
Step 2: system-reminder を確認する
会話ログの中に <system-reminder> ブロックがあれば、そこに deferred tools の一覧があります。呼び出そうとしたツール名がリストに含まれているかチェックします。
Step 3: ToolSearch を実行してから再試行する
// スキーマをロードしてから呼び出す
await ToolSearch({ query: "select:mcp__workspace__bash" });
const output = await mcp__workspace__bash({ command: "ls /tmp" });これだけで解消することがほとんどです。
よくある間違いパターン
パターン1: 呼び出し順序の誤り
deferred tools は「一度でもツールを呼んだセッション」では問題ないように見えて、新しいセッションや別のエージェントを起動したタイミングで再度 deferred 状態に戻ります。スケジュールタスクのように毎回新しいセッションが立ち上がる環境では特に注意が必要です。
// ❌ 前のセッションでは動いていたのに今回は失敗するパターン
const result = await mcp__workspace__bash({ command: "echo hello" });
// → 新しいセッションのため deferred 状態に戻っている// ✅ セッション冒頭で必要なツールをまとめてロード
await ToolSearch({ query: "select:mcp__workspace__bash,TaskCreate,TaskUpdate" });
// 以降は通常通り呼び出せるパターン2: プラグインを追加した直後
MCP サーバーやプラグインを新しく追加した直後、そのツールのスキーマはまだ deferred 状態です。「プラグインをインストールしたのにツールが動かない」という問い合わせの多くは、ToolSearch を実行していないことが原因です。Canva や Figma などのプラグインを追加した直後にそのツールを使おうとして失敗するケースがこれにあたります。
パターン3: ToolSearch の結果を await せずに呼び出す
// ❌ ToolSearch の完了を待たずに呼び出す(非同期処理のミス)
ToolSearch({ query: "select:WebSearch" }); // await していない
WebSearch({ query: "..." }); // スキーマがまだ未ロードの可能性// ✅ 必ず await して、ToolSearch の完了を確認してから呼び出す
await ToolSearch({ query: "select:WebSearch" });
const result = await WebSearch({ query: "..." });パターン4: エラーを別の原因と勘違いする
InputValidationError は「パラメータの値が間違っている」エラーだと思い込んでパラメータを変えても解決しないケースがあります。エラーメッセージに「schema not loaded」や「tool not found」が含まれている場合は、パラメータではなくスキーマのロード自体が問題です。
Cowork スケジュールタスクでの実装パターン
Dolice Labs では1日16本の記事を4サイトに自動投稿するスケジュールタスクを運用しています。各タスクは毎回新しいセッションで起動するため、セッション冒頭で必要ツールをまとめてロードするパターンを取り入れました。
// セッション冒頭でまとめてロード
async function initializeTools() {
await ToolSearch({
query: "select:mcp__workspace__bash,TaskCreate,TaskUpdate,WebSearch"
});
// スキーマロード完了
}
// タスク本体
async function runDailyArticleGeneration() {
await initializeTools();
// 以降は deferred エラーなしで呼び出せる
const wsResult = await mcp__workspace__bash({
command: 'ls -d /sessions/*/mnt/Dolice\\ Labs 2>/dev/null | head -1'
});
const ws = wsResult.stdout.trim();
// ... 以降の処理
}このパターンを採用してから、「ツールが見つからない」系のエラーでスケジュールタスクが止まることがなくなりました。ToolSearch の呼び出し自体は数百ミリ秒程度で、タスク全体の実行時間に対して無視できる水準です。
MCP プラグインの場合の注意点
Canva・Figma・Slack などの外部サービス連携ツールは MCP プラグイン経由で追加されるため、名前が mcp__{uuid}__{tool-name} のような形式になります。
// Canva プラグインのツール例
await ToolSearch({ query: "select:mcp__4cebb999-208a-460c-96cf-29ee38abf5d6__generate-design" });
const design = await mcp__4cebb999__generate_design({ ... });UUID が長くて扱いにくい場合は、キーワード検索でも取得できます。
// キーワードで検索してスキーマを取得
await ToolSearch({ query: "canva generate design" });ToolSearch の応答を確認してデバッグを深める
ToolSearch は単なるスキーマローダーとして使うだけでなく、応答内容を確認することで問題を深掘りすることもできます。
// ToolSearch の結果を変数に受け取る
const toolInfo = await ToolSearch({ query: "select:mcp__workspace__bash" });
console.log(JSON.stringify(toolInfo, null, 2));応答には、ロードされたツールの名前・説明・パラメータスキーマが含まれます。期待するツールが返ってきているか、パラメータ名や型が正しいかをここで確認できます。
特に MCP プラグイン経由のツールは、実際のパラメータ名が直感と異なることがあります。たとえば generate-design ツールが prompt ではなく description を期待しているといった差異です。ToolSearch の応答を一度でも確認しておくと、その後の開発が格段に楽になります。
スケジュールタスク全体での位置づけ
Dolice Labs では国際芸術賞 17 冠のアーティスト活動と並行して、個人開発のアプリ事業(累計 5,000 万 DL)のマーケティングコンテンツも自動生成しています。スケジュールタスクは深夜から早朝にかけて動き、私が眠っている間に記事を生成して GitHub にプッシュします。
この仕組みが安定して動くためには、ToolSearch によるスキーマ事前ロードが欠かせません。タスクが「途中で止まっていた」と翌朝気づいても、ログを見れば InputValidationError: schema not loaded と記録されているケースは多く、原因が即座に分かるようになりました。
エラーログを残しておくことも重要です。どのツールがどのタイミングで deferred 状態に戻るかのパターンが見えてくると、ToolSearch の呼び出しタイミングをさらに最適化できます。
全体を振り返って
InputValidationError でツール呼び出しが失敗する場合、まず deferred tools の問題を疑ってください。対処法は3ステップです。
<system-reminder>の deferred tools リストにツール名があるか確認するawait ToolSearch({ query: "select:ToolName" })でスキーマをロードする- await の完了を確認してから呼び出す
毎回新しいセッションが起動するスケジュールタスクや自動化パイプラインでは、セッション冒頭でまとめてロードしておくのがシンプルで確実です。パラメータを変えても直らないときはスキーマのロード状態を疑う——それだけで多くのケースが解決します。