PrefectHQ/fastmcp · error · TypeError

Invalid first argument: {type(name_or_fn)}

Error message

Invalid first argument: {type(name_or_fn)}

What it means

The first positional argument of @prompt must be a function/routine, a string name, or None. Anything else (int, dict, class instance, etc.) cannot be interpreted, so prompt() raises TypeError listing the actual type received. This is the catch-all branch after the routine/string/None checks fail.

Source

Thrown at fastmcp_slim/fastmcp/prompts/function_prompt.py:445

            auth=auth,
        )
        target = fn.__func__ if isinstance(fn, staticmethod | MethodType) else fn
        cast(Any, target).__fastmcp__ = metadata
        return fn

    def decorator(fn: F, prompt_name: str | None) -> F:
        return attach_metadata(fn, prompt_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")
        prompt_name = name_or_fn
    elif name_or_fn is None:
        prompt_name = name
    else:
        raise TypeError(f"Invalid first argument: {type(name_or_fn)}")

    def wrapper(fn: F) -> F:
        return decorator(fn, prompt_name)

    return wrapper

View on GitHub (pinned to 1f02114297)

Solutions

  1. Pass the undecorated function: @prompt(fn), not the result of calling it
  2. If you intended to name the prompt, pass a string: @prompt('my_name') used as a factory over a def
  3. Drop accidental parentheses: @prompt(my_func) not @prompt(my_func())
  4. Wrap non-standard callables (objects with __call__) in a plain def before decorating

Example fix

// before
@prompt(get_prompt_fn())
def my_prompt(): ...
// after
@prompt(get_prompt_fn)
Defensive patterns

Strategy: type-guard

Validate before calling

import inspect
first = get_prompt_fn  # not get_prompt_fn()
if not (inspect.isroutine(first) or isinstance(first, (str, type(None)))):
    raise TypeError(f'bad @prompt first argument: {type(first).__name__}')

Type guard

def is_prompt_decorator_arg(v) -> bool:
    return inspect.isroutine(v) or isinstance(v, str) or v is None

Try / catch

try:
    p = prompt(candidate)
except TypeError as e:
    if 'Invalid first argument' in str(e):
        p = prompt(lambda **kw: candidate(**kw))  # wrap non-routine callable
    else:
        raise

Prevention

When it happens

Trigger: @prompt(123), @prompt({'name': 'x'}), @prompt(some_object), or accidental calls like @prompt(fn()) that pass the RESULT of invoking the function (e.g. a returned dict) instead of the function itself.

Common situations: Calling the decorated function at decoration time by mistake (@prompt(my_func()) instead of @prompt(my_func)); parens confusion between @prompt and @prompt(); passing a Mock or other callable object that inspect.isroutine does not recognize.

Related errors


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