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

  1. Remove response_title/response_description from the call and set title/description on each field via pydantic Field(...) or dataclasses.field(metadata=...)/Field
  2. 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
  3. 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

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


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/5abe1c67149d4997. Report an issue: GitHub.