{"record":{"id":"db078a213e7a2e0e","repo":"langchain-ai/langchain","slug":"tool-definition-for-name-must-include-valid-type","errorCode":null,"errorMessage":"Tool definition for {name} must include valid type annotations for argument 'args_schema' to behave as expected.\nExpected annotation of 'Type[BaseModel]' but got '{args_schema_type}'.\nExpected class looks like:\n{typehint_mandate}","messagePattern":"Tool definition for (.+?) must include valid type annotations for argument 'args_schema' to behave as expected\\.\nExpected annotation of 'Type\\[BaseModel\\]' but got '(.+?)'\\.\nExpected class looks like:\n(.+?)","errorType":"exception","errorClass":"SchemaAnnotationError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/tools/base.py","lineNumber":473,"sourceCode":"        if args_schema_type is not None and args_schema_type == BaseModel:\n            # Throw errors for common mis-annotations.\n            # TODO: Use get_args / get_origin and fully\n            # specify valid annotations.\n            typehint_mandate = \"\"\"\nclass ChildTool(BaseTool):\n    ...\n    args_schema: Type[BaseModel] = SchemaClass\n    ...\"\"\"\n            name = cls.__name__\n            msg = (\n                f\"Tool definition for {name} must include valid type annotations\"\n                f\" for argument 'args_schema' to behave as expected.\\n\"\n                f\"Expected annotation of 'Type[BaseModel]'\"\n                f\" but got '{args_schema_type}'.\\n\"\n                f\"Expected class looks like:\\n\"\n                f\"{typehint_mandate}\"\n            )\n            raise SchemaAnnotationError(msg)\n\n    name: str\n    \"\"\"The unique name of the tool that clearly communicates its purpose.\"\"\"\n\n    description: str\n    \"\"\"Used to tell the model how/when/why to use the tool.\n\n    You can provide few-shot examples as a part of the description.\n    \"\"\"\n\n    args_schema: Annotated[ArgsSchema | None, SkipValidation()] = Field(\n        default=None, description=\"The tool schema.\"\n    )\n    \"\"\"Pydantic model class to validate and parse the tool's input arguments.\n\n    Args schema should be either:\n\n    - A subclass of `pydantic.BaseModel`.","sourceCodeStart":455,"sourceCodeEnd":491,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/tools/base.py#L455-L491","documentation":"`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.","triggerScenarios":"`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.","commonSituations":"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.","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."],"exampleFix":"# before\nclass SearchTool(BaseTool):\n    name = 'search'\n    description = 'Search'\n    args_schema = SearchArgs  # no annotation\n# after\nfrom typing import Type\nfrom pydantic import BaseModel\n\nclass SearchTool(BaseTool):\n    name = 'search'\n    description = 'Search'\n    args_schema: Type[BaseModel] = SearchArgs","handlingStrategy":"validation","validationCode":"import inspect\n\ndef has_annotated_args_schema(cls) -> bool:\n    hints = cls.__dict__.get('__annotations__', {})\n    return 'args_schema' in hints  # annotation must be declared in the subclass itself\n\nassert has_annotated_args_schema(MyTool)","typeGuard":null,"tryCatchPattern":"from langchain_core.tools.base import SchemaAnnotationError\n\ntry:\n    t = MyTool()\nexcept SchemaAnnotationError as e:\n    if 'args_schema' in str(e):\n        # add 'args_schema: Type[BaseModel] = MySchema' to the class, then retry\n        MyTool = rebuild_with_annotation(MyTool)\n        t = MyTool()\n    else:\n        raise","preventionTips":["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."],"tags":["tool","base-tool","schema-annotation","subclassing"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}