kmail.at
← learning

langchain · difficulty ◆◆◆

Tool Schemas with Unsupported Top-Level Composition (langchain-anthropic 1.5.4)

Fail fast on schemas Anthropic cannot express - before your tool call blows up in production.

Your Pydantic Union is a tool schema that Anthropic simply cannot understand - and now you find out immediately.

2026-08-06 · 9 min read

$ pip install -U langchain-anthropic==1.5.4

What it does

Anthropic\u2019s tool-calling API accepts schemas describing the function calls a model can make. When a schema uses top-level composition patterns - a root oneOf, an allOf, or a bare array type without an items key - older langchain-anthropic would silently drop those fields, raise an opaque validation error, or send a malformed schema that fails at runtime. The fix in langchain-anthropic==1.5.4 (PR #39273) intercepts these unsupported patterns before serialization: it either flattens them into a compatible form or raises a clear, actionable error upfront.

Why it matters

When you bind tools for Claude via bind_tools or the @tool decorator, LangChain converts your Python signatures into JSON schemas for Anthropic. Real projects use Pydantic models with discriminated unions (oneOf), optional composition (allOf), or bare list types at the top level - valid in LangChain\u2019s internal schema system but unsupported by Anthropic. Before this fix you only discovered the mismatch when a specific tool was actually called, producing confusing runtime errors. Now the failure surfaces at schema-build time with a clear message, saving hours of production debugging.

Example

$ Bind a Pydantic model with a top-level Union and see the new upfront behavior
Schema validation passed — tools bound successfully
Tool call result: AIMessage(content='...' additional_kwargs={'tool_calls': [...]})

When the schema contains an unrecoverable pattern, you now get: Schema error (now clear upfront): Unsupported top-level composition in tool schema for 'SearchTool': top-level 'oneOf' is not supported by Anthropic. Consider flattening the schema or using a root 'object' type.

$ Inspect which schema shapes trigger the guard
class SearchTool(BaseModel):
    query: str
    filter: Union[str, int, None] = None   # top-level oneOf
class BatchIDs(BaseModel):
    ids: list                              # bare list, no items=
# Both now fail or flatten at bind time, not at call time

Common flags

#39273
fix(anthropic): handle tool schemas with unsupported top-level composition.
bind_tools
Binds Pydantic/tool schemas to a Claude model for tool calling.
convert_to_anthropic_tool_schema
Converts a LangChain schema to Anthropic\u2019s expected JSON format.

History

Schema dialects rarely match

LangChain\u2019s internal schema model is richer than what any single provider accepts. Anthropic\u2019s tool spec, in particular, does not support root-level composition keywords. For a long time the gap was only discovered lazily, at runtime. The 1.5.4 fix adds an eager validation pass, shifting the failure left in the development cycle - the classic win of fail-fast validation over fail-late.

Fun facts

Pros & cons

pros

  • + Fail-fast schema validation
  • + Clear, actionable error messages
  • + Flattens compatible patterns automatically

cons

  • − Some schemas need manual refactoring
  • − Anthropic-specific; other providers differ

Takeaways

  1. 1Bind tools inside a try/except that logs the schema.
  2. 2Prefer root-object schemas with named properties for Anthropic.
  3. 3Upgrade to langchain-anthropic>=1.5.4 to get eager validation.

Related commands

← all learning