PrefectHQ/fastmcp · error · TypeError
To decorate a classmethod, use @classmethod above @prompt. S
Error message
To decorate a classmethod, use @classmethod above @prompt. See https://gofastmcp.com/servers/prompts#using-with-methods
What it means
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.
Source
Thrown at fastmcp_slim/fastmcp/prompts/function_prompt.py:413
def prompt(
name_or_fn: str | Callable[..., Any] | None = None,
*,
name: str | None = None,
version: str | int | None = None,
title: str | None = None,
description: str | None = None,
icons: list[Icon] | None = None,
tags: set[str] | None = None,
meta: dict[str, Any] | None = None,
auth: AuthCheck | list[AuthCheck] | None = None,
) -> Any:
"""Standalone decorator to mark a function as an MCP prompt.
Returns the original function with metadata attached. Register with a server
using mcp.add_prompt().
"""
if isinstance(name_or_fn, classmethod):
raise TypeError(
"To decorate a classmethod, use @classmethod above @prompt. "
"See https://gofastmcp.com/servers/prompts#using-with-methods"
)
def attach_metadata(fn: F, prompt_name: str | None) -> F:
metadata = PromptMeta(
name=prompt_name,
version=version,
title=title,
description=description,
icons=icons,
tags=tags,
meta=meta,
auth=auth,
)
target = fn.__func__ if isinstance(fn, staticmethod | MethodType) else fn
cast(Any, target).__fastmcp__ = metadata
return fnView on GitHub (pinned to 1f02114297)
Solutions
- Reorder the decorators so @classmethod is above @prompt: @classmethod @prompt def 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
Example fix
// before
class Prompts:
@prompt
@classmethod
def greeting(cls): ...
// after
class Prompts:
@classmethod
@prompt
def greeting(cls): ... Defensive patterns
Strategy: type-guard
Validate before calling
import inspect
if isinstance(name_or_fn, classmethod):
raise TypeError('put @classmethod above @prompt') Type guard
def is_valid_prompt_target(obj) -> bool:
return not isinstance(obj, classmethod) and (inspect.isroutine(obj) or isinstance(obj, str) or obj is None) Try / catch
try:
decorated = prompt(my_method)
except TypeError as e:
if 'classmethod' in str(e):
raise SyntaxError('use @classmethod above @prompt') from e
raise Prevention
- 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
When it happens
Trigger: Writing: class Foo: @prompt @classmethod def my_prompt(cls): ... — i.e. @prompt placed above @classmethod, so prompt receives a classmethod descriptor as name_or_fn.
Common situations: 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.
Related errors
- Cannot specify name both as first argument and keyword
- Invalid first argument: {type(name_or_fn)}
- To decorate a classmethod, use @classmethod above @prompt. S
- Cannot specify both a name as first argument and as keyword
- First argument to @{decorator_name} must be a function, stri
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/af21e02c7435a439.
Report an issue: GitHub.