{"record":{"id":"5abe1c67149d4997","repo":"PrefectHQ/fastmcp","slug":"response-title-and-response-description-are-only-s","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/elicitation.py","lineNumber":186,"sourceCode":"    has_response_metadata = (\n        response_title is not None or response_description is not None\n    )\n\n    if response_type is None:\n        raise TypeError(_NONE_RESPONSE_TYPE_ERROR)\n\n    if isinstance(response_type, dict):\n        config = _parse_dict_syntax(response_type)\n    elif isinstance(response_type, list):\n        config = _parse_list_syntax(response_type)\n    elif get_origin(response_type) is list:\n        config = _parse_generic_list(response_type)\n    elif _is_scalar_type(response_type):\n        config = _parse_scalar_type(response_type)\n    else:\n        # Other types (dataclass, BaseModel, etc.) - use directly\n        if has_response_metadata:\n            raise TypeError(\n                \"response_title and response_description are only supported when \"\n                \"response_type is a scalar, Literal, Enum, or the dict/list \"\n                \"shorthand forms. For BaseModel or dataclass response types, use \"\n                \"Field(title=..., description=...) on the individual fields.\"\n            )\n        return ElicitConfig(\n            schema=get_elicitation_schema(response_type),\n            response_type=response_type,\n            is_raw=False,\n        )\n\n    if has_response_metadata:\n        _apply_value_metadata(config.schema, response_title, response_description)\n    return config\n\n\ndef _apply_value_metadata(\n    schema: dict[str, Any],","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/elicitation.py#L168-L204","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nclass Prefs(BaseModel):\n    theme: str\nresult = await ctx.elicit(\"Pick\", response_type=Prefs, response_title=\"Preferences\")\n// after\nclass Prefs(BaseModel):\n    theme: str = Field(title=\"Theme\", description=\"UI color theme\")\nresult = await ctx.elicit(\"Pick\", response_type=Prefs)","handlingStrategy":"validation","validationCode":"from pydantic import BaseModel\nif has_response_metadata and isinstance(response_type, type) and issubclass(response_type, BaseModel):\n    raise TypeError('put Field(title=..., description=...) on the model fields instead')","typeGuard":"def supports_response_metadata(response_type) -> bool:\n    import typing\n    from pydantic import BaseModel\n    from dataclasses import is_dataclass\n    if isinstance(response_type, type) and (\n        is_dataclass(response_type)\n        or (isinstance(response_type, type) and issubclass(response_type, BaseModel))\n    ):\n        return False\n    return True  # scalars, Literal, Enum, dict/list shorthand","tryCatchPattern":"try:\n    result = await ctx.elicit(msg, response_type=MyModel, response_title='T')\nexcept TypeError as e:\n    if 'response_title' in str(e):\n        result = await ctx.elicit(msg, response_type=MyModel)  # fields carry titles","preventionTips":["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"],"tags":["elicitation","pydantic","schema","fastmcp"],"backgroundTag":"unsupported-elicit-response-metadata","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}