{"record":{"id":"50a731817b5ed36a","repo":"zylon-ai/private-gpt","slug":"array-items-must-be-a-dictionary-representing-js","errorCode":null,"errorMessage":"Array 'items' must be a dictionary representing JSON Schema","messagePattern":"Array 'items' must be a dictionary representing JSON Schema","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"private_gpt/chat/schema_models.py","lineNumber":125,"sourceCode":"    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\")\n    if not schema:\n        return\n\n    # Composition keywords at the top level are valid without a \"type\" field.\n    for composition_key in (\"allOf\", \"anyOf\", \"oneOf\"):\n        if composition_key in schema:\n            for sub_schema in schema[composition_key]:\n                _validate_json_schema_item(sub_schema, strict=False)","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/chat/schema_models.py#L107-L143","documentation":"Raised by _validate_json_schema_item when an array schema's \"items\" value is not a dict. JSON Schema requires items to be a schema object; this validator enforces dict form because it recursively builds Pydantic models from it. Tuples, lists (per-item form), or strings like \"string\" all trigger it.","triggerScenarios":"Passing {\"type\": \"array\", \"items\": \"string\"} (type as a bare string), {\"items\": [ {\"type\": \"string\"}, {\"type\": \"number\"} ]} (tuple-validation array form), or items set to None within a schema sent to create_model_from_json_schema.","commonSituations":"Translating from Python type hints or OpenAPI specs where item types are strings; using the legacy JSON Schema array-form items; YAML configs where items collapses to a scalar.","solutions":["Wrap the item type in a schema object: {\"items\": {\"type\": \"string\"}} instead of {\"items\": \"string\"}.","Replace tuple-form items arrays with {\"items\": {\"anyOf\": [ ... ]}}.","If items comes from user input, coerce/validate it to a dict before calling the API."],"exampleFix":"// before\n{\"type\": \"array\", \"items\": \"string\"}\n\n// after\n{\"type\": \"array\", \"items\": {\"type\": \"string\"}}","handlingStrategy":"validation","validationCode":"def coerce_items(node: dict) -> None:\n    if node.get(\"type\") == \"array\":\n        items = node.get(\"items\")\n        if isinstance(items, str):\n            node[\"items\"] = {\"type\": items}\n        elif isinstance(items, list):\n            node[\"items\"] = {\"anyOf\": items}\n        if not isinstance(node.get(\"items\"), dict):\n            raise ValueError(f\"Bad items for array: {items!r}\")","typeGuard":"def has_dict_items(s: dict) -> bool:\n    return s.get(\"type\") != \"array\" or isinstance(s.get(\"items\"), dict)","tryCatchPattern":"try:\n    create_model_from_json_schema(schema)\nexcept ValueError as e:\n    raise HTTPException(400, detail=str(e)) from e","preventionTips":["Always wrap item types as objects: {\"items\": {\"type\": ...}}.","Avoid the legacy tuple-form items array.","Validate schema shape with a unit test before integrating user input."],"tags":["json-schema","validation","structured-output","pydantic"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}