langchain-ai/langchain · error · TypeError
Tool input must be str or dict. If dict, dict arguments must
Error message
Tool input must be str or dict. If dict, dict arguments must be typed. Either annotate types (e.g., with TypedDict) or pass arg_types into `.as_tool` to specify. {e} What it means
When converting a Runnable to a tool (.as_tool / convert_runnable_to_tool), LangChain derives the args schema from runnable.InputType's type hints. If InputType is untyped (plain dict without hints) or malformed, get_type_hints raises TypeError, which is re-raised with guidance: dict inputs must be typed, or arg_types passed explicitly.
Source
Thrown at libs/core/langchain_core/tools/convert.py:428
return f"Takes {input_schema}."
def _get_schema_from_runnable_and_arg_types(
runnable: Runnable[Any, Any],
name: str,
arg_types: dict[str, type] | None = None,
) -> type[BaseModel]:
"""Infer `args_schema` for tool."""
if arg_types is None:
try:
arg_types = get_type_hints(runnable.InputType)
except TypeError as e:
msg = (
"Tool input must be str or dict. If dict, dict arguments must be "
"typed. Either annotate types (e.g., with TypedDict) or pass "
f"arg_types into `.as_tool` to specify. {e}"
)
raise TypeError(msg) from e
fields = {key: (key_type, Field(...)) for key, key_type in arg_types.items()}
return cast("type[BaseModel]", create_model(name, **fields)) # type: ignore[call-overload]
def convert_runnable_to_tool(
runnable: Runnable[Any, Any],
args_schema: TypeBaseModel | None = None,
*,
name: str | None = None,
description: str | None = None,
arg_types: dict[str, type] | None = None,
) -> BaseTool:
"""Convert a `Runnable` into a `BaseTool`.
Args:
runnable: The `Runnable` to convert.
args_schema: The schema for the tool's input arguments.
name: The name of the tool.View on GitHub (pinned to e32fa9a52e)
Solutions
- Pass arg_types: runnable.as_tool(arg_types={'text': str, 'count': int})
- Or type the function parameter with a TypedDict/pydantic model so get_type_hints succeeds
- For single-string inputs, annotate the parameter as str
Example fix
# before
def _run(data): # untyped dict
return process(data)
tool = RunnableLambda(_run).as_tool() # TypeError
# after
class Data(TypedDict):
text: str
count: int
def _run(data: Data) -> str:
return process(data)
tool = RunnableLambda(_run).as_tool()
# or quick fix: RunnableLambda(_run).as_tool(arg_types={"text": str, "count": int}) Defensive patterns
Strategy: validation
Validate before calling
from typing import get_type_hints
def as_tool_typed(runnable, name="tool", arg_types=None):
if arg_types is None:
try:
arg_types = get_type_hints(runnable.InputType)
except TypeError:
arg_types = None
if not arg_types:
msg = "Runnable input is untyped; pass arg_types=..."
raise ValueError(msg)
return runnable.as_tool(name=name, arg_types=arg_types) Type guard
from typing import get_type_hints
def has_typed_input(runnable) -> bool:
try:
return bool(get_type_hints(runnable.InputType))
except TypeError:
return False Try / catch
try:
t = runnable.as_tool()
except TypeError as e:
if "must be typed" in str(e):
t = runnable.as_tool(arg_types={"text": str})
else:
raise Prevention
- Always annotate RunnableLambda functions with a TypedDict parameter when tools are planned
- Keep TypedDicts at module level so get_type_hints resolves forward references
- Pass arg_types explicitly when wrapping third-party, untyped runnables
When it happens
Trigger: runnable.as_tool() where the RunnableLambda's function parameter is an untyped dict; InputType is dict (bare) or object; a TypedDict defined in a local scope whose hints cannot be resolved.
Common situations: Wrapping quick lambdas like RunnableLambda(lambda data: process(data)) into tools; chains whose input type inference falls back to untyped dict; TypedDicts failing get_type_hints due to forward references / local classes.
Related errors
- Runnable must have an object schema.
- Runnable without name for tool constructor
- Name must be a string for tool constructor
- Too many arguments to single-input tool {self.name}.
- Invalid args_schema: expected BaseModel or dict, got {args_s
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/b8d742ca6c243740.
Report an issue: GitHub.