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
- Pass an explicit name: from_function(fn, name='double')
- Set name in the ToolMeta object passed as metadata
- 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
- Never register bare lambdas; always wrap in a named def
- Lint rule: flag FunctionTool.from_function calls whose fn is a lambda without name=
- Store tool names alongside functions in registries
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
- You must provide a name for lambda functions
- Cannot pass both 'metadata' and individual parameters to fro
- To decorate a classmethod, use @classmethod above @tool. See
- Accessing `{cls_name}.{camel}` is deprecated; MCP SDK v2 ren
- {cls.__name__} does not define KEY_PREFIX. Component keys wi
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/30eaf12d37eaf8bd.
Report an issue: GitHub.