Claude Tool Use Failed Validation — Schema Fix (2026) | AI Error Hub
Anthropic Claude Tool Use Severity: High HTTP 400

Claude Tool Use Failed Validation

Your tool definitions don't match Claude's schema requirements. Common with copy-pasted OpenAI function schemas, missing input_schema, or invalid JSON Schema syntax.

Error code: invalid_request_error HTTP: 400 Category: Tool Use Last tested: Nov 14, 2026
Quick Fix (TL;DR)

Claude tools require exactly three top-level fields: name, description, and input_schema. The schema uses input_schema (NOT parameters like OpenAI). Type must be "object" with a properties map and an optional required array.

The Error Message You're Seeing

Response body
HTTP/1.1 400 Bad Request

{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "tools.0: Field required 'input_schema'"
  }
}

Common variants: "tools.0.input_schema.type: must be 'object'", "tools.0.name: does not match required pattern", "tool_choice.name: not found in tools".

What Actually Causes This Error

38%
Using OpenAI-style function schemaOpenAI uses parameters; Anthropic uses input_schema. Direct copy-paste fails.
24%
Invalid tool name formatNames must match ^[a-zA-Z0-9_-]{1,64}$. Spaces, dots, and special characters rejected.
18%
Missing type: "object" at schema rootThe input_schema root must have type: "object" explicitly.
12%
Invalid JSON Schema syntaxUsing JSON Schema keywords Claude doesn't support (like oneOf) or malformed property definitions.
8%
tool_choice references undefined toolForcing tool_choice: {name: "get_weather"} but no tool named "get_weather" in the tools array.

Fixes That Work (Tested Nov 2026)

1Use the Correct Anthropic Schema Format

Python · correct tool schema
tools = [{ "name": "get_weather", "description": "Get current weather for a location", "input_schema": { # NOT "parameters" "type": "object", # Required at root "properties": { "location": { "type": "string", "description": "City name, e.g. Karachi" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] } }, "required": ["location"] } }] response = client.messages.create( model="claude-sonnet-4-5", max_tokens=1024, tools=tools, messages=[{"role": "user", "content": "Weather in Karachi?"}] )
Migrating from OpenAI?

OpenAI: {name, description, parameters: {...}}. Anthropic: {name, description, input_schema: {...}}. The nested structure is nearly identical — just rename parameters to input_schema.

2Validate Tool Names Against Regex

Python · validation helper
import re TOOL_NAME_PATTERN = re.compile(r"^[a-zA-Z0-9_-]{1,64}$") def validate_tools(tools): for tool in tools: if not TOOL_NAME_PATTERN.match(tool["name"]): raise ValueError(f"Invalid tool name: {tool['name']}") if tool["input_schema"].get("type") != "object": raise ValueError(f"Tool {tool['name']}: input_schema.type must be 'object'") if "properties" not in tool["input_schema"]: raise ValueError(f"Tool {tool['name']}: missing properties") validate_tools(tools) # Fail fast before API call

3Handle tool_choice Correctly

Python · tool_choice options
# Let Claude decide (default) tool_choice = {"type": "auto"} # Force any tool use tool_choice = {"type": "any"} # Force specific tool — name must exist in tools array tool_choice = {"type": "tool", "name": "get_weather"} # Prevent tool use entirely tool_choice = {"type": "none"} response = client.messages.create( model="claude-sonnet-4-5", max_tokens=1024, tools=tools, tool_choice=tool_choice, messages=[{"role": "user", "content": "Weather in Karachi?"}] )

Preventing This Error Going Forward

  • Define tool schemas as typed classes. Use Pydantic (Python) or Zod (TypeScript) — generate JSON schema automatically.
  • Validate tools on startup. Fail fast if a tool schema is malformed.
  • Test with a minimal example first. Verify tool structure with a simple 1-parameter tool before adding complexity.
  • Don't use unsupported JSON Schema keywords. Claude supports a subset — avoid oneOf, allOf, if/then/else.
  • Keep tool descriptions clear and specific. Better descriptions reduce Claude's tool-selection errors.
AR
Tested by Ahmed R.
Researcher · AI Error Hub
Last verified: Nov 14, 2026 · SDK: anthropic-sdk-python 0.42

Frequently Asked Questions

A subset. Supported: type, properties, required, enum, description, nested objects/arrays. Unsupported (or unreliable): oneOf, anyOf, allOf, if/then/else, $ref. Stick to the supported subset for reliability.

No hard cap documented, but performance degrades with 20+ tools. If you have many tools, group them by domain and use dynamic selection to pass only relevant tools per request.

No. Names must match ^[a-zA-Z0-9_-]{1,64}$ — letters, numbers, underscores, and hyphens only. Use underscores for namespacing: weather_get_current instead of weather/get-current.

Even with forced tool use, Claude may include a brief text response before or after the tool call. If you need pure structured output, parse only the tool_use block and ignore text blocks. Or use structured outputs when available.

Yes — dramatically improves tool selection accuracy. Format: "Use this when the user asks about X. Example: 'What's the weather?' → get_weather(location='Karachi')". Claude uses these signals heavily.