{"record":{"id":"f053742580c854bf","repo":"PrefectHQ/fastmcp","slug":"elicitation-schema-field-prop-name-has-type","errorCode":null,"errorMessage":"Elicitation schema field '{prop_name}' has type '{prop_type}' which is not a primitive type. Only {ALLOWED_TYPES} are allowed in elicitation schemas.","messagePattern":"Elicitation schema field '(.+?)' has type '(.+?)' which is not a primitive type\\. Only (.+?) are allowed in elicitation schemas\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/elicitation.py","lineNumber":513,"sourceCode":"                if union_schemas and all(\"const\" in s for s in union_schemas):\n                    continue  # Allowed: {\"type\": \"array\", \"items\": {\"anyOf\": [{\"const\": ...}, ...]}}\n\n            # Reject other array types (e.g., arrays of primitives without enum pattern)\n            raise TypeError(\n                f\"Elicitation schema field '{prop_name}' is an array, but arrays are only allowed \"\n                \"when items are enums (for multi-select). Only enum arrays are supported in elicitation schemas.\"\n            )\n\n        # Check for nested objects (not allowed)\n        if prop_type == \"object\":\n            raise TypeError(\n                f\"Elicitation schema field '{prop_name}' is an object, but nested objects are not allowed. \"\n                \"Elicitation schemas must be flat objects with primitive properties only.\"\n            )\n\n        # Check if it's a primitive type\n        if prop_type not in ALLOWED_TYPES:\n            raise TypeError(\n                f\"Elicitation schema field '{prop_name}' has type '{prop_type}' which is not \"\n                f\"a primitive type. Only {ALLOWED_TYPES} are allowed in elicitation schemas.\"\n            )\n","sourceCodeStart":495,"sourceCodeEnd":517,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/elicitation.py#L495-L517","documentation":"FastMCP elicitation schemas must be flat objects whose properties are primitive JSON types. validate_elicitation_json_schema inspects each property's declared 'type' and raises TypeError if it is not one of ALLOWED_TYPES (string, number, integer, boolean, plus enum variants). Nested objects and arbitrary arrays are rejected because elicitation responses must map to simple form fields.","triggerScenarios":"Calling get_elicitation_schema (or passing an elicitation schema through a tool) where a property in properties has a 'type' like 'object', 'array' (non-enum), or is missing/unrecognized, causing prop_type not in ALLOWED_TYPES.","commonSituations":"Developers porting a full JSON Schema designed for structured output (nested dicts, arrays of objects) into an elicitation request; hand-written schemas with typos in the type name; schemas generated from pydantic models with nested model fields.","solutions":["Flatten the schema: replace nested objects with individual primitive properties (e.g. use 'address_line1', 'city' instead of an 'address' object).","Use an enum array for multi-select instead of arbitrary arrays: {'type':'array','items':{'type':'string','enum':[...]}} which is allowed.","Remove or rename properties with misspelled types so each property.type is one of the allowed primitives.","If complex input is required, split elicitation into multiple sequential primitive-only requests or collect data via a tool instead."],"exampleFix":"// before\nschema = {\"type\": \"object\", \"properties\": {\"address\": {\"type\": \"object\", \"properties\": {\"city\": {\"type\": \"string\"}}}}}\n// after\nschema = {\"type\": \"object\", \"properties\": {\"city\": {\"type\": \"string\"}}}","handlingStrategy":"validation","validationCode":"ALLOWED = {\"string\", \"number\", \"integer\", \"boolean\"}\ndef validate_flat(schema):\n    for name, prop in schema.get(\"properties\", {}).items():\n        t = prop.get(\"type\")\n        items = prop.get(\"items\", {})\n        if t == \"array\" and items.get(\"type\") != \"string\" or items.get(\"enum\") is None and t == \"array\":\n            raise TypeError(f\"{name}: arrays must be enum arrays\")\n        if t not in ALLOWED and t != \"array\":\n            raise TypeError(f\"{name}: type '{t}' is not a primitive\")","typeGuard":"def is_primitive_schema(prop: dict) -> bool:\n    return prop.get(\"type\") in {\"string\", \"number\", \"integer\", \"boolean\"}","tryCatchPattern":"try:\n    schema = tool._get_elicitation_schema()\nexcept TypeError as e:\n    logger.error(\"Flatten elicitation schema: %s\", e)\n    schema = flatten_schema(schema)","preventionTips":["Design elicitation schemas as flat forms with primitive fields only","Use enum arrays for multi-select instead of arrays of objects","Derive schemas from flat pydantic models, not nested ones","Unit-test get_elicitation_schema() for every tool that elicits input"],"tags":["elicitation","schema-validation","json-schema"],"backgroundTag":"elicitation-schema-not-primitive","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}