langchain-ai/langchain · error · ValueError
Name must be a string for tool constructor
Error message
Name must be a string for tool constructor
What it means
In tool(name_or_callable, runnable=...) function-style usage, the first argument must be a string naming the tool. This raises when something other than a str (e.g. the function itself or a Runnable) was passed positionally together with runnable=.
Source
Thrown at libs/core/langchain_core/tools/convert.py:367
return _tool_factory
if len(args) != 0:
# Triggered if a user attempts to use positional arguments that
# do not exist in the function signature
# e.g., @tool("name", runnable, "extra_arg")
# Here, "extra_arg" is not a valid argument
msg = "Too many arguments for tool decorator. A decorator "
raise ValueError(msg)
if runnable is not None:
# tool is used as a function
# for instance tool_from_runnable = tool("name", runnable)
if not name_or_callable:
msg = "Runnable without name for tool constructor"
raise ValueError(msg)
if not isinstance(name_or_callable, str):
msg = "Name must be a string for tool constructor"
raise ValueError(msg)
return _create_tool_factory(name_or_callable)(runnable)
if name_or_callable is not None:
if callable(name_or_callable) and hasattr(name_or_callable, "__name__"):
# Used as a decorator without parameters
# @tool
# def my_tool():
# pass
return _create_tool_factory(name_or_callable.__name__)(name_or_callable)
if isinstance(name_or_callable, str):
# Used with a new name for the tool
# @tool("search")
# def my_tool():
# pass
#
# or
#
# @tool("search", parse_docstring=True)
# def my_tool():View on GitHub (pinned to e32fa9a52e)
Solutions
- Use only a string name with runnable=: tool('name', runnable=runnable)
- To wrap a function, use the decorator form or call the factory: tool('name')(my_func)
- To compose runnables, pipe them first (a | b) and then convert the composed chain
Example fix
# before
t = tool(my_func, runnable=my_runnable)
# after
t = tool("my_tool", runnable=my_runnable | my_func) Defensive patterns
Strategy: type-guard
Validate before calling
def tool_from_runnable(runnable, name):
if not isinstance(name, str):
msg = f"name must be str, got {type(name).__name__}"
raise TypeError(msg)
return tool(name, runnable=runnable) Type guard
def is_str_name(x: object) -> bool:
return isinstance(x, str) and bool(x) Try / catch
try:
t = tool(first_arg, runnable=runnable)
except ValueError as e:
if "Name must be a string" in str(e):
t = tool(str(first_arg), runnable=runnable)
else:
raise Prevention
- When using runnable=, make the first argument a literal string name
- Never pass the callable positionally together with runnable=
- Review tool() call sites during code review for mixed positional/keyword misuse
When it happens
Trigger: tool(my_func, runnable=my_runnable); tool(my_runnable, runnable=my_runnable); any non-string first argument combined with the runnable keyword.
Common situations: Mixing decorator-style and function-style usage in one call; passing both a callable and a runnable expecting them to be composed.
Related errors
- Runnable without name for tool constructor
- Runnable must have an object schema.
- Too many arguments for tool decorator. A decorator
- The first argument must be a string or a callable with a __n
- Tool input must be str or dict. If dict, dict arguments must
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/008989a7edde9867.
Report an issue: GitHub.