PrefectHQ/fastmcp · error · TypeError
response_title and response_description are only supported w
Error message
response_title and response_description are only supported when response_type is a scalar, Literal, Enum, or the dict/list shorthand forms. For BaseModel or dataclass response types, use Field(title=..., description=...) on the individual fields.
What it means
response_title and response_description metadata are implemented by wrapping the generated schema for scalars, Literals, Enums, and the dict/list shorthand forms. For BaseModel or dataclass response types the schema comes directly from the model's fields, so a wrapper title/description has nowhere to go — parse_elicit_response_type raises TypeError and directs you to annotate the model's fields with Field(title=..., description=...) instead.
Source
Thrown at fastmcp_slim/fastmcp/server/elicitation.py:186
has_response_metadata = (
response_title is not None or response_description is not None
)
if response_type is None:
raise TypeError(_NONE_RESPONSE_TYPE_ERROR)
if isinstance(response_type, dict):
config = _parse_dict_syntax(response_type)
elif isinstance(response_type, list):
config = _parse_list_syntax(response_type)
elif get_origin(response_type) is list:
config = _parse_generic_list(response_type)
elif _is_scalar_type(response_type):
config = _parse_scalar_type(response_type)
else:
# Other types (dataclass, BaseModel, etc.) - use directly
if has_response_metadata:
raise TypeError(
"response_title and response_description are only supported when "
"response_type is a scalar, Literal, Enum, or the dict/list "
"shorthand forms. For BaseModel or dataclass response types, use "
"Field(title=..., description=...) on the individual fields."
)
return ElicitConfig(
schema=get_elicitation_schema(response_type),
response_type=response_type,
is_raw=False,
)
if has_response_metadata:
_apply_value_metadata(config.schema, response_title, response_description)
return config
def _apply_value_metadata(
schema: dict[str, Any],View on GitHub (pinned to 1f02114297)
Solutions
- Remove response_title/response_description from the call and set title/description on each field via pydantic Field(...) or dataclasses.field(metadata=...)/Field
- If a single titled value is all you need, switch response_type to a scalar or the dict shorthand where the metadata kwargs are supported
- Keep models self-describing so the client renders field titles from the model itself
Example fix
// before
class Prefs(BaseModel):
theme: str
result = await ctx.elicit("Pick", response_type=Prefs, response_title="Preferences")
// after
class Prefs(BaseModel):
theme: str = Field(title="Theme", description="UI color theme")
result = await ctx.elicit("Pick", response_type=Prefs) Defensive patterns
Strategy: validation
Validate before calling
from pydantic import BaseModel
if has_response_metadata and isinstance(response_type, type) and issubclass(response_type, BaseModel):
raise TypeError('put Field(title=..., description=...) on the model fields instead') Type guard
def supports_response_metadata(response_type) -> bool:
import typing
from pydantic import BaseModel
from dataclasses import is_dataclass
if isinstance(response_type, type) and (
is_dataclass(response_type)
or (isinstance(response_type, type) and issubclass(response_type, BaseModel))
):
return False
return True # scalars, Literal, Enum, dict/list shorthand Try / catch
try:
result = await ctx.elicit(msg, response_type=MyModel, response_title='T')
except TypeError as e:
if 'response_title' in str(e):
result = await ctx.elicit(msg, response_type=MyModel) # fields carry titles Prevention
- For BaseModel/dataclass elicitations, describe fields with Field(title=..., description=...), never wrapper kwargs
- Reserve response_title/response_description for scalar/Literal/Enum/dict-list calls
- When migrating from shorthand to a model, delete the metadata kwargs at the same time
- Keep models self-documenting so client UIs render titles from field metadata
When it happens
Trigger: Calling `ctx.elicit("msg", response_type=SomeBaseModel, response_title="T")` or with response_description set while response_type is a pydantic BaseModel or a dataclass.
Common situations: Copy-pasting an elicit call that worked with a scalar type and swapping in a model; adding titles for UI rendering without realizing models carry their own field metadata; refactoring from dict shorthand to a typed model while keeping the metadata kwargs.
Related errors
- Dict response_type cannot be empty.
- Invalid list response_type format. Received: {lst}
- ctx.elicit() requires a response_type. The empty-schema form
- Elicitation response missing required 'value' field.
- Elicitation expected an empty response, but received: {conte
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/5abe1c67149d4997.
Report an issue: GitHub.