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 requires at least one of func or coroutine; passing neither leaves the tool with nothing to execute, so creation fails immediately with ValueError.

Source

Thrown at libs/core/langchain_core/tools/simple.py:199

        Args:
            func: The function to create the tool from.
            name: The name of the tool.
            description: The description of the tool.
            return_direct: Whether to return the output directly.
            args_schema: The schema of the tool's input arguments.
            coroutine: The asynchronous version of the function.
            **kwargs: Additional arguments to pass to the tool.

        Returns:
            The tool.

        Raises:
            ValueError: If the function is not provided.
        """
        if func is None and coroutine is None:
            msg = "Function and/or coroutine must be provided"
            raise ValueError(msg)
        return cls(
            name=name,
            func=func,
            coroutine=coroutine,
            description=description,
            return_direct=return_direct,
            args_schema=args_schema,
            **kwargs,
        )

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Pass a function: StructuredTool.from_function(my_func)
  2. If constructing from a class, pass the callable explicitly (e.g. instance.method)
  3. Add an assert func is not None or coroutine is not None before the call in dynamic tool factories

Example fix

# before
tool = StructuredTool.from_function(
    name="t", description="...", func=None
)

# after
async def run(query: str) -> str: ...
tool = StructuredTool.from_function(
    name="t", description="...", coroutine=run
)
Defensive patterns

Strategy: validation

Validate before calling

def build_structured_tool(func=None, coroutine=None, **kw):
    if func is None and coroutine is None:
        msg = "Refusing to create a tool with no implementation"
        raise ValueError(msg)
    return StructuredTool.from_function(func=func, coroutine=coroutine, **kw)

Type guard

def has_implementation(func: object, coroutine: object) -> bool:
    return callable(func) or callable(coroutine)

Try / catch

try:
    t = StructuredTool.from_function(**tool_kwargs)
except ValueError as e:
    if "must be provided" in str(e):
        tool_kwargs["func"] = default_noop
        t = StructuredTool.from_function(**tool_kwargs)
    else:
        raise

Prevention

When it happens

Trigger: StructuredTool.from_function(name='t', description='...') with no func/coroutine; passing func=None explicitly and omitting coroutine.

Common situations: Building tools from configuration where the function reference failed to resolve (None from a factory); subclass scaffolding copy-paste where the function argument was dropped.

Related errors


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