langchain-ai/langchain · error · ValueError

Function and/or coroutine must be provided

Error message

Function and/or coroutine must be provided

What it means

StructuredTool.from_function uses func or coroutine both as the executable and as the source of the name and schema. With neither provided there is no source_function, so construction aborts with ValueError before any schema inference.

Source

Thrown at libs/core/langchain_core/tools/structured.py:201

            TypeError: If the `args_schema` is not a `BaseModel` or dict.

        Examples:
            ```python
            def add(a: int, b: int) -> int:
                \"\"\"Add two numbers\"\"\"
                return a + b
            tool = StructuredTool.from_function(add)
            tool.run(1, 2) # 3

            ```
        """
        if func is not None:
            source_function = func
        elif coroutine is not None:
            source_function = coroutine
        else:
            msg = "Function and/or coroutine must be provided"
            raise ValueError(msg)
        name = name or source_function.__name__
        if args_schema is None and infer_schema:
            # schema name is appended within function
            args_schema = create_schema_from_function(
                name,
                source_function,
                parse_docstring=parse_docstring,
                error_on_invalid_docstring=error_on_invalid_docstring,
                filter_args=_filter_schema_args(source_function),
            )
        description_ = description
        if description is None and not parse_docstring:
            description_ = source_function.__doc__ or None
        if description_ is None and args_schema:
            if isinstance(args_schema, type) and is_basemodel_subclass(args_schema):
                description_ = args_schema.__doc__
                if (
                    description_

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Supply func (sync) and/or coroutine (async) to from_function
  2. Guard dynamic construction: raise early if the resolved callable is None
  3. For pure data tools, subclass StructuredTool and implement _run/_arun instead

Example fix

# before
fn = registry.get(tool_cfg.name)      # may return None
tool = StructuredTool.from_function(fn, name=tool_cfg.name)

# after
fn = registry.get(tool_cfg.name)
if fn is None:
    msg = f"Unknown tool {tool_cfg.name}"
    raise KeyError(msg)
tool = StructuredTool.from_function(fn, name=tool_cfg.name)
Defensive patterns

Strategy: validation

Validate before calling

def structured_tool_from(fn, **kw):
    if not callable(fn):
        msg = f"from_function needs a callable, got {fn!r}"
        raise TypeError(msg)
    return StructuredTool.from_function(fn, **kw)

Type guard

from collections.abc import Callable

def is_tool_source(fn: object) -> bool:
    return callable(fn) and hasattr(fn, "__name__")

Try / catch

try:
    t = StructuredTool.from_function(source, name=name)
except ValueError as e:
    if "must be provided" in str(e):
        msg = f"Tool source for {name!r} resolved to None"
        raise RuntimeError(msg) from e
    raise

Prevention

When it happens

Trigger: StructuredTool.from_function() with neither func nor coroutine; conditional code paths that pass func only when a lookup succeeds and silently forward None.

Common situations: Factory functions mapping config entries to tools where the callable registration failed; refactoring from_function calls and dropping the first argument.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/da09ecebe0f58664. Report an issue: GitHub.