PrefectHQ/fastmcp · error
Invalid first argument: {type(name_or_fn)}
Error message
Invalid first argument: {type(name_or_fn)} What it means
The first positional argument of @tool must be a callable (direct decoration), a string (tool name), or None. Anything else (int, dict, function-like object that isn't a routine, etc.) falls through to this TypeError reporting the offending type.
Source
Thrown at fastmcp_slim/fastmcp/tools/function_tool.py:621
run_in_thread=run_in_thread,
)
target = fn.__func__ if isinstance(fn, staticmethod | MethodType) else fn
cast(Any, target).__fastmcp__ = metadata
return fn
def decorator(fn: F, tool_name: str | None) -> F:
return attach_metadata(fn, tool_name)
if inspect.isroutine(name_or_fn):
return decorator(name_or_fn, name)
elif isinstance(name_or_fn, str):
if name is not None:
raise TypeError("Cannot specify name both as first argument and keyword")
tool_name = name_or_fn
elif name_or_fn is None:
tool_name = name
else:
raise TypeError(f"Invalid first argument: {type(name_or_fn)}")
def wrapper(fn: F) -> F:
return decorator(fn, tool_name)
return wrapper
View on GitHub (pinned to 1f02114297)
Solutions
- Pass a callable to decorate directly: @tool\ndef fn(...)
- Pass a string name: @tool("my_name")
- Pass nothing: @tool with keyword options only
Example fix
// before
@tool({"name": "x"})
def fn(x: int) -> int: ...
// after
@tool("x")
def fn(x: int) -> int: ... Defensive patterns
Strategy: type-guard
Validate before calling
def check_tool_first_arg(name_or_fn):
if name_or_fn is None or isinstance(name_or_fn, str):
return
if callable(name_or_fn):
return
raise TypeError(f'Invalid first argument: {type(name_or_fn)}') Type guard
def is_valid_tool_first_arg(x) -> bool:
return x is None or isinstance(x, str) or (callable(x) and not isinstance(x, (int, dict, list))) Try / catch
try:
tool = tool_decorator(x)
except TypeError as e:
if 'Invalid first argument' in str(e):
tool = tool_decorator(name=x['name'])(fn) # recover correct form Prevention
- Only pass a callable, a string, or nothing as the first decorator argument
- Don't pass config dicts/metadata objects positionally to @tool
- Check decorator usage examples in docs when adding options
When it happens
Trigger: @tool(42), @tool(some_config_dict), @tool(instance) where instance is not a routine/string/None — any misuse of the decorator's first positional slot.
Common situations: Passing a configuration object or metadata as the first argument thinking it's the name; accidentally calling @tool(fn_result) instead of @tool; typos like @tool(name) where name is undefined-ish object.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- Cannot specify name both as first argument and keyword
- Cannot pass both 'metadata' and individual parameters to fro
- The @resource decorator requires a URI. Use @resource('uri')
- Expected Prompt or @prompt-decorated function, got {type(pro
- To decorate a classmethod, use @classmethod above @prompt. S
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/daf279587f79016b.
Report an issue: GitHub.