PrefectHQ/fastmcp · error

You must provide a name for lambda functions

Error message

You must provide a name for lambda functions

What it means

A lambda function's __name__ is always '<lambda>', which is not a valid tool identifier, so from_function() raises ValueError unless an explicit name (via parameter or metadata) is supplied. The library refuses to guess a usable name for anonymous functions.

Source

Thrown at fastmcp_slim/fastmcp/tools/function_tool.py:301

                version=version,
                title=title,
                description=description,
                icons=icons,
                tags=tags,
                output_schema=output_schema,
                annotations=annotations,
                meta=meta,
                task=task,
                timeout=timeout,
                auth=auth,
                run_in_thread=True if run_in_thread is None else run_in_thread,
            )

        parsed_fn = ParsedFunction.from_function(fn)
        func_name = metadata.name or parsed_fn.name

        if func_name == "<lambda>":
            raise ValueError("You must provide a name for lambda functions")

        # Inline sync execution has no cancellation checkpoints, so
        # anyio.fail_after cannot preempt the call — the timeout would be
        # silently ignored. Reject the combination so users make an
        # explicit choice. Async generators are async even though
        # is_coroutine_function returns False for them; the generator's
        # iteration has checkpoints, so timeout enforcement still works.
        if (
            metadata.timeout is not None
            and not metadata.run_in_thread
            and not is_coroutine_function(fn)
            and not inspect.isasyncgenfunction(fn)
        ):
            raise ValueError(
                f"Tool {func_name!r}: timeout cannot be enforced when "
                "run_in_thread=False on a sync function. Inline execution has "
                "no cancellation checkpoints, so the timeout would be a no-op. "
                "Either drop the timeout or remove run_in_thread=False and "

View on GitHub (pinned to 1f02114297)

Solutions

  1. Pass an explicit name: from_function(fn, name='double')
  2. Set name in the ToolMeta object passed as metadata
  3. Convert the lambda to a named def function

Example fix

// before
FunctionTool.from_function(lambda x: x * 2)
// after
FunctionTool.from_function(lambda x: x * 2, name="double")
Defensive patterns

Strategy: validation

Validate before calling

def ensure_named(fn, name=None, metadata=None):
    resolved = name or (getattr(metadata, 'name', None) if metadata else None) or getattr(fn, '__name__', '')
    if resolved in ('', '<lambda>'):
        raise ValueError('Lambda requires an explicit tool name')
    return resolved

Type guard

def is_lambda(fn) -> bool:
    return callable(fn) and getattr(fn, '__name__', '') == '<lambda>'

Try / catch

try:
    tool = FunctionTool.from_function(fn)
except ValueError as e:
    if 'name for lambda' in str(e):
        tool = FunctionTool.from_function(fn, name=default_name_for(fn))

Prevention

When it happens

Trigger: FunctionTool.from_function(lambda x: x * 2) with no name= argument and metadata=None or metadata.name=None.

Common situations: Quickly registering a small transformation as a tool inline; code generators or decorators wrapping lambdas without naming them; refactoring a named helper into a lambda.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/30eaf12d37eaf8bd. Report an issue: GitHub.