{"record":{"id":"bd3e6ba7b0fee71a","repo":"zylon-ai/private-gpt","slug":"schema-must-define-a-type-field","errorCode":null,"errorMessage":"Schema must define a 'type' field","messagePattern":"Schema must define a 'type' field","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"private_gpt/chat/schema_models.py","lineNumber":117,"sourceCode":"\n    if \"anyOf\" in schema:\n        if not isinstance(schema[\"anyOf\"], list):\n            raise ValueError(\"'anyOf' must be an array of schemas\")\n        for sub_schema in schema[\"anyOf\"]:\n            _validate_json_schema_item(sub_schema, strict=False)\n        return  # anyOf schemas don't need type field\n\n    if \"allOf\" in schema:\n        if not isinstance(schema[\"allOf\"], list):\n            raise ValueError(\"'allOf' must be an array of schemas\")\n        for sub_schema in schema[\"allOf\"]:\n            _validate_json_schema_item(sub_schema, strict=False)\n        return  # allOf schemas don't need type field\n\n    # Regular schema validation\n    if \"type\" not in schema:\n        if strict:\n            raise ValueError(\"Schema must define a 'type' field\")\n        else:\n            return  # Non-strict mode allows missing type\n\n    if schema[\"type\"] == \"array\" and \"items\" not in schema:\n        raise ValueError(\"Array schemas must define 'items'\")\n\n    if schema[\"type\"] == \"array\" and not isinstance(schema.get(\"items\"), dict):\n        raise ValueError(\"Array 'items' must be a dictionary representing JSON Schema\")\n\n    # Recursively validate array items\n    if schema[\"type\"] == \"array\":\n        _validate_json_schema_item(schema.get(\"items\", {}))\n\n\ndef _validate_json_schema(schema: dict[str, Any]) -> None:\n    \"\"\"Validate that the schema is a valid JSON Schema object.\"\"\"\n    if not isinstance(schema, dict):\n        raise ValueError(\"Schema must be a dictionary representing JSON Schema\")","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/chat/schema_models.py#L99-L135","documentation":"Raised by _validate_json_schema_item in private_gpt/chat/schema_models.py when a JSON schema passed to create_model_from_json_schema lacks a 'type' field in strict mode. Schemas using anyOf/allOf are exempt and return early; only a 'regular' schema without 'type' triggers this. Strict mode is used for top-level and array-item schemas, so the root schema must always declare its type.","triggerScenarios":"Calling create_model_from_json_schema (or ChatContextFilter/structured-output APIs that build models from schemas) with a top-level schema like {\"description\": \"...\"} or {\"properties\": {...}} that has no \"type\" key. Also an array whose items schema omits \"type\", since items are validated strictly.","commonSituations":"User-supplied structured-output schemas from OpenAI tool specs or frontends that assume 'an object with properties' implies type; schemas copied from JSON Schema examples that use $ref at top level; LLM-generated schemas omitting the type keyword.","solutions":["Add \"type\": \"object\" (or the intended type) to the top-level schema dict before passing it in.","If the schema intentionally has no single type, wrap the variants under \"anyOf\" or \"allOf\", which are accepted without a type field.","If validating array items, ensure each item schema also declares \"type\" — items are validated with strict=True.","Log the offending schema before validation to find which node is missing the field."],"exampleFix":"// before\nschema = {\"properties\": {\"city\": {\"type\": \"string\"}}}\nmodel = create_model_from_json_schema(schema)\n\n// after\nschema = {\"type\": \"object\", \"properties\": {\"city\": {\"type\": \"string\"}}}\nmodel = create_model_from_json_schema(schema)","handlingStrategy":"validation","validationCode":"def has_type_or_composition(schema: dict) -> bool:\n    return \"type\" in schema or any(k in schema for k in (\"anyOf\", \"allOf\", \"oneOf\"))\n\nif not has_type_or_composition(schema):\n    schema = {\"type\": \"object\", **schema}","typeGuard":"def is_typed_schema(s: object) -> bool:\n    return isinstance(s, dict) and (\"type\" in s or any(k in s for k in (\"anyOf\", \"allOf\", \"oneOf\")))","tryCatchPattern":"try:\n    model = create_model_from_json_schema(schema)\nexcept ValueError as e:\n    raise HTTPException(400, f\"Invalid schema: {e}\") from e","preventionTips":["Normalize user-supplied schemas to inject type=object before calling the API.","Validate schemas client-side with the same rules (type or anyOf/allOf/oneOf required).","Log the schema on failure to pinpoint the offending node."],"tags":["json-schema","validation","structured-output","pydantic"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}