langchain-ai/langchain · error · SchemaAnnotationError
Tool definition for {name} must include valid type annotatio
Error message
Tool definition for {name} must include valid type annotations for argument 'args_schema' to behave as expected.
Expected annotation of 'Type[BaseModel]' but got '{args_schema_type}'.
Expected class looks like:
{typehint_mandate} What it means
`SchemaAnnotationError` raised when subclassing `BaseTool` and overriding `args_schema` WITHOUT a type annotation: langchain needs the class-level annotation (`args_schema: Type[BaseModel] = MySchema`) to distinguish 'overriding the schema' from 'setting an instance value'. A bare `args_schema = MySchema` breaks schema detection for all instances of the class.
Source
Thrown at libs/core/langchain_core/tools/base.py:473
if args_schema_type is not None and args_schema_type == BaseModel:
# Throw errors for common mis-annotations.
# TODO: Use get_args / get_origin and fully
# specify valid annotations.
typehint_mandate = """
class ChildTool(BaseTool):
...
args_schema: Type[BaseModel] = SchemaClass
..."""
name = cls.__name__
msg = (
f"Tool definition for {name} must include valid type annotations"
f" for argument 'args_schema' to behave as expected.\n"
f"Expected annotation of 'Type[BaseModel]'"
f" but got '{args_schema_type}'.\n"
f"Expected class looks like:\n"
f"{typehint_mandate}"
)
raise SchemaAnnotationError(msg)
name: str
"""The unique name of the tool that clearly communicates its purpose."""
description: str
"""Used to tell the model how/when/why to use the tool.
You can provide few-shot examples as a part of the description.
"""
args_schema: Annotated[ArgsSchema | None, SkipValidation()] = Field(
default=None, description="The tool schema."
)
"""Pydantic model class to validate and parse the tool's input arguments.
Args schema should be either:
- A subclass of `pydantic.BaseModel`.View on GitHub (pinned to e32fa9a52e)
Solutions
- Add the annotation exactly as mandated: `args_schema: Type[BaseModel] = MySchema` (or `Type[BaseModel] | dict` for JSON-schema dicts, matching the error's template).
- Prefer the simpler `@tool(args_schema=MySchema)` decorator path, which handles this for you.
- Copy the `typehint_mandate` snippet printed in the error message verbatim into the class body.
Example fix
# before
class SearchTool(BaseTool):
name = 'search'
description = 'Search'
args_schema = SearchArgs # no annotation
# after
from typing import Type
from pydantic import BaseModel
class SearchTool(BaseTool):
name = 'search'
description = 'Search'
args_schema: Type[BaseModel] = SearchArgs Defensive patterns
Strategy: validation
Validate before calling
import inspect
def has_annotated_args_schema(cls) -> bool:
hints = cls.__dict__.get('__annotations__', {})
return 'args_schema' in hints # annotation must be declared in the subclass itself
assert has_annotated_args_schema(MyTool) Try / catch
from langchain_core.tools.base import SchemaAnnotationError
try:
t = MyTool()
except SchemaAnnotationError as e:
if 'args_schema' in str(e):
# add 'args_schema: Type[BaseModel] = MySchema' to the class, then retry
MyTool = rebuild_with_annotation(MyTool)
t = MyTool()
else:
raise Prevention
- Always annotate overrides: args_schema: Type[BaseModel] = MySchema.
- Prefer the @tool decorator over manual BaseTool subclasses.
- Copy the mandate snippet from the error message verbatim.
When it happens
Trigger: `class MyTool(BaseTool): args_schema = MySchema # missing ': Type[BaseModel]' annotation` then `MyTool().args` — the unannotated class attribute is treated as an instance default, not a schema override, and the validator raises at instance creation.
Common situations: Porting pre-0.x tool examples that assigned `args_schema` without annotation; IDE auto-removing 'redundant' annotations; defining structured tools by subclassing BaseTool instead of using the `@tool` decorator and missing the mandated style.
Related errors
- Arg {docstring_arg} in docstring not found in function signa
- Function {func} contains a mix of Pydantic v1 and v2 annotat
- args_schema must be a subclass of pydantic BaseModel or a JS
- String tool inputs are not allowed when using tools with JSO
- When tool includes an InjectedToolCallId argument, tool must
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/db078a213e7a2e0e.
Report an issue: GitHub.