{"record":{"id":"af21e02c7435a439","repo":"PrefectHQ/fastmcp","slug":"to-decorate-a-classmethod-use-classmethod-above","errorCode":null,"errorMessage":"To decorate a classmethod, use @classmethod above @prompt. See https://gofastmcp.com/servers/prompts#using-with-methods","messagePattern":"To decorate a classmethod, use @classmethod above @prompt\\. See https://gofastmcp\\.com/servers/prompts#using-with-methods","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/prompts/function_prompt.py","lineNumber":413,"sourceCode":"def prompt(\n    name_or_fn: str | Callable[..., Any] | None = None,\n    *,\n    name: str | None = None,\n    version: str | int | None = None,\n    title: str | None = None,\n    description: str | None = None,\n    icons: list[Icon] | None = None,\n    tags: set[str] | None = None,\n    meta: dict[str, Any] | None = None,\n    auth: AuthCheck | list[AuthCheck] | None = None,\n) -> Any:\n    \"\"\"Standalone decorator to mark a function as an MCP prompt.\n\n    Returns the original function with metadata attached. Register with a server\n    using mcp.add_prompt().\n    \"\"\"\n    if isinstance(name_or_fn, classmethod):\n        raise TypeError(\n            \"To decorate a classmethod, use @classmethod above @prompt. \"\n            \"See https://gofastmcp.com/servers/prompts#using-with-methods\"\n        )\n\n    def attach_metadata(fn: F, prompt_name: str | None) -> F:\n        metadata = PromptMeta(\n            name=prompt_name,\n            version=version,\n            title=title,\n            description=description,\n            icons=icons,\n            tags=tags,\n            meta=meta,\n            auth=auth,\n        )\n        target = fn.__func__ if isinstance(fn, staticmethod | MethodType) else fn\n        cast(Any, target).__fastmcp__ = metadata\n        return fn","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/prompts/function_prompt.py#L395-L431","documentation":"The @prompt decorator cannot be applied directly to a classmethod object. When name_or_fn is a classmethod (i.e. @prompt is stacked BELOW @classmethod), the decorator raises TypeError immediately with a doc link. The supported ordering is @classmethod on top and @prompt underneath, so @prompt sees the plain function.","triggerScenarios":"Writing:\nclass Foo:\n    @prompt\n    @classmethod\n    def my_prompt(cls): ...\n— i.e. @prompt placed above @classmethod, so prompt receives a classmethod descriptor as name_or_fn.","commonSituations":"Copy-pasting method-based prompt examples and flipping the decorator order; migrating tools to prompts while keeping classmethod layout; misunderstanding which decorator must be outermost.","solutions":["Reorder the decorators so @classmethod is above @prompt:\n@classmethod\n@prompt\ndef my_prompt(cls): ...","Alternatively convert to a plain @staticmethod or module-level function and decorate with @prompt","See the linked docs page for the supported method pattern"],"exampleFix":"// before\nclass Prompts:\n    @prompt\n    @classmethod\n    def greeting(cls): ...\n// after\nclass Prompts:\n    @classmethod\n    @prompt\n    def greeting(cls): ...","handlingStrategy":"type-guard","validationCode":"import inspect\nif isinstance(name_or_fn, classmethod):\n    raise TypeError('put @classmethod above @prompt')","typeGuard":"def is_valid_prompt_target(obj) -> bool:\n    return not isinstance(obj, classmethod) and (inspect.isroutine(obj) or isinstance(obj, str) or obj is None)","tryCatchPattern":"try:\n    decorated = prompt(my_method)\nexcept TypeError as e:\n    if 'classmethod' in str(e):\n        raise SyntaxError('use @classmethod above @prompt') from e\n    raise","preventionTips":["Always place @classmethod above @prompt when decorating methods","Prefer staticmethod or plain functions for prompts to avoid ordering pitfalls","Remember classmethod objects don't carry prompt metadata after decoration"],"tags":["prompts","decorator","classmethod","typeerror"],"backgroundTag":"decorator-order-mismatch","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}