{"record":{"id":"0c0040bd25c27a9f","repo":"PrefectHQ/fastmcp","slug":"invalid-first-argument-type-name-or-fn","errorCode":null,"errorMessage":"Invalid first argument: {type(name_or_fn)}","messagePattern":"Invalid first argument: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/prompts/function_prompt.py","lineNumber":445,"sourceCode":"            auth=auth,\n        )\n        target = fn.__func__ if isinstance(fn, staticmethod | MethodType) else fn\n        cast(Any, target).__fastmcp__ = metadata\n        return fn\n\n    def decorator(fn: F, prompt_name: str | None) -> F:\n        return attach_metadata(fn, prompt_name)\n\n    if inspect.isroutine(name_or_fn):\n        return decorator(name_or_fn, name)\n    elif isinstance(name_or_fn, str):\n        if name is not None:\n            raise TypeError(\"Cannot specify name both as first argument and keyword\")\n        prompt_name = name_or_fn\n    elif name_or_fn is None:\n        prompt_name = name\n    else:\n        raise TypeError(f\"Invalid first argument: {type(name_or_fn)}\")\n\n    def wrapper(fn: F) -> F:\n        return decorator(fn, prompt_name)\n\n    return wrapper\n","sourceCodeStart":427,"sourceCodeEnd":451,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/prompts/function_prompt.py#L427-L451","documentation":"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.","triggerScenarios":"@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.","commonSituations":"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.","solutions":["Pass the undecorated function: @prompt(fn), not the result of calling it","If you intended to name the prompt, pass a string: @prompt('my_name') used as a factory over a def","Drop accidental parentheses: @prompt(my_func) not @prompt(my_func())","Wrap non-standard callables (objects with __call__) in a plain def before decorating"],"exampleFix":"// before\n@prompt(get_prompt_fn())\ndef my_prompt(): ...\n// after\n@prompt(get_prompt_fn)","handlingStrategy":"type-guard","validationCode":"import inspect\nfirst = get_prompt_fn  # not get_prompt_fn()\nif not (inspect.isroutine(first) or isinstance(first, (str, type(None)))):\n    raise TypeError(f'bad @prompt first argument: {type(first).__name__}')","typeGuard":"def is_prompt_decorator_arg(v) -> bool:\n    return inspect.isroutine(v) or isinstance(v, str) or v is None","tryCatchPattern":"try:\n    p = prompt(candidate)\nexcept TypeError as e:\n    if 'Invalid first argument' in str(e):\n        p = prompt(lambda **kw: candidate(**kw))  # wrap non-routine callable\n    else:\n        raise","preventionTips":["Never call the function inside the decorator: @prompt(fn), not @prompt(fn())","Wrap non-standard callables (objects with __call__, odd partials) in a plain def before decorating","Keep decorator usage to the three supported forms: @prompt, @prompt('name'), @prompt(name='name')"],"tags":["prompts","decorator","typeerror","arguments"],"backgroundTag":"invalid-decorator-argument","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}