PrefectHQ/fastmcp · error · PromptError
Error rendering prompt {self.name!r}: {e}
Error message
Error rendering prompt {self.name!r}: {e} What it means
When the prompt's render function raises any exception that is not a FastMCPError, render() logs the full traceback and re-raises it wrapped in a PromptError, chained via 'from e' so the original cause is preserved. This normalizes arbitrary user-function failures (syntax errors, type errors, network failures inside the fn) into a single prompt-domain error type. FastMCPError subclasses pass through unwrapped.
Source
Thrown at fastmcp_slim/fastmcp/prompts/function_prompt.py:363
# self.fn is wrapped by without_injected_parameters which handles
# dependency resolution internally
if is_coroutine_function(self.fn):
result = await type_adapter.validate_python(kwargs)
else:
# Run sync functions in threadpool to avoid blocking the event loop
result = await call_sync_fn_in_threadpool(
type_adapter.validate_python, kwargs
)
# Handle sync wrappers that return awaitables (e.g., partial(async_fn))
if inspect.isawaitable(result):
result = await result
return self.convert_result(result)
except FastMCPError:
raise
except Exception as e:
logger.exception(f"Error rendering prompt {self.name}")
raise PromptError(f"Error rendering prompt {self.name!r}: {e}") from e
@overload
def prompt(fn: F) -> F: ...
@overload
def prompt(
name_or_fn: str,
*,
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,
) -> Callable[[F], F]: ...
@overload
def prompt(View on GitHub (pinned to 1f02114297)
Solutions
- Read the chained original exception in the traceback (the 'caused by' section) to find the real root cause inside your prompt function
- Fix the bug in the prompt function itself — PromptError is only a wrapper
- Catch PromptError at the call site and fall back to a user-friendly message
- If your function intentionally raises a domain error, raise a FastMCPError subclass so it propagates unwrapped
Example fix
// before
def get_weather(city: str) -> str:
return api.fetch(city)['temp'] # raises KeyError
// after
def get_weather(city: str) -> str:
data = api.fetch(city)
return data.get('temp', 'unknown') Defensive patterns
Strategy: try-catch
Validate before calling
import inspect sig = inspect.signature(prompt_fn) sig.bind(**arguments) # raises TypeError early if args mismatch
Try / catch
try:
result = await prompt.render(arguments)
except PromptError as e:
logger.error('prompt failed: %s (cause: %r)', e, e.__cause__)
result = fallback_prompt_result
except FastMCPError:
raise # domain errors pass through unwrapped Prevention
- Always inspect e.__cause__ / the chained traceback, not just the PromptError message
- Keep prompt functions simple and move risky I/O into guarded helpers
- Test prompt functions directly with pytest before registering them
- Raise FastMCPError subclasses inside prompt fns for errors you want unwrapped
When it happens
Trigger: The function decorated with @prompt raises any non-FastMCP exception when invoked with the supplied arguments — e.g. TypeError from wrong argument types after string conversion, KeyError inside the function, API call failures, division by zero.
Common situations: The prompt function calls an external LLM/API that is down; argument type conversion produces an unexpected type (e.g. 'None' string) that the fn chokes on; a refactor changed the fn signature so a keyword mismatches; template rendering inside the fn raises.
Related errors
- messages[{i}] must be Message, got {type(item).__name__}. Us
- messages must be str or list[Message], got {type(messages)._
- Subclasses must implement render()
- messages[{i}] must be Message or str, got {type(item).__name
- Prompt must return str, list[Message], or PromptResult, got
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/b3466cecba1a6c9d.
Report an issue: GitHub.