PrefectHQ/fastmcp · error · TypeError

Elicitation schema must be an object schema, got type '{sche

Error message

Elicitation schema must be an object schema, got type '{schema.get('type')}'. Elicitation schemas are limited to flat objects with primitive properties only.

What it means

MCP elicitation only supports top-level object JSON schemas whose properties are primitives. validate_elicitation_json_schema checks schema['type'] == 'object' first; anything else (string, array, no type, etc.) is rejected with this TypeError before the elicitation is sent to the client.

Source

Thrown at fastmcp_slim/fastmcp/server/elicitation.py:415

    This ensures the schema is compatible with MCP elicitation requirements:
    - Must be an object schema
    - Must only contain primitive field types (string, number, integer, boolean)
    - Must be flat (no nested objects or arrays of objects)
    - Allows const fields (for Literal types) and enum fields (for Enum types)
    - Only primitive types and their nullable variants are allowed

    Args:
        schema: The JSON schema to validate

    Raises:
        TypeError: If the schema doesn't meet MCP elicitation requirements
    """
    ALLOWED_TYPES = {"string", "number", "integer", "boolean"}

    # Check that the schema is an object
    if schema.get("type") != "object":
        raise TypeError(
            f"Elicitation schema must be an object schema, got type '{schema.get('type')}'. "
            "Elicitation schemas are limited to flat objects with primitive properties only."
        )

    properties = schema.get("properties", {})

    for prop_name, prop_schema in properties.items():
        prop_type = prop_schema.get("type")

        # Handle nullable types
        if isinstance(prop_type, list):
            if "null" in prop_type:
                prop_type = [t for t in prop_type if t != "null"]
                if len(prop_type) == 1:
                    prop_type = prop_type[0]
        elif prop_schema.get("nullable", False):
            continue  # Nullable with no other type is fine

View on GitHub (pinned to 1f02114297)

Solutions

  1. Wrap the value in a BaseModel or dataclass so the schema is a flat object with primitive fields
  2. Use the scalar shorthand forms (str, bool, Literal, Enum, dict/list syntax) which FastMCP wraps into an object automatically
  3. If passing a schema dict directly, make it {"type": "object", "properties": {...}}

Example fix

// before
schema = {"type": "string"}
// after
from pydantic import BaseModel
class Answer(BaseModel):
    name: str
await ctx.elicit(response_type=Answer)
Defensive patterns

Strategy: validation

Validate before calling

def ensure_object_schema(schema: dict) -> dict:
    if schema.get("type") != "object":
        raise TypeError(f"elicitation schema must be an object, got {schema.get('type')!r}")
    return schema

ensure_object_schema(get_elicitation_schema(MyModel))

Type guard

def is_object_schema(schema: object) -> bool:
    return isinstance(schema, dict) and schema.get("type") == "object"

Try / catch

try:
    schema = get_elicitation_schema(response_type)
except TypeError as e:
    if "must be an object schema" in str(e):
        logger.error("wrap scalar/root types in a BaseModel or use the scalar shorthand")
        return None
    raise

Prevention

When it happens

Trigger: Defining an elicitation response type whose generated JSON schema is not an object — e.g. response_type=str (via a path that skips wrapping), a Pydantic RootModel, or a hand-built schema dict like {"type": "string"} passed through get_elicitation_schema.

Common situations: Hand-rolling elicitation schemas and forgetting to wrap the primitive in an object with properties; using RootModel or a NewType that collapses to a scalar schema; a library upgrade changing how types are wrapped.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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