zylon-ai/private-gpt · error · ValueError

'anyOf' must be an array of schemas

Error message

'anyOf' must be an array of schemas

What it means

Pydantic field-validator error on SkillFile.path when the value contains a backslash. Skill file paths must use '/' as the sole separator (canonical, cross-platform form); Windows-style paths are rejected with this ValueError and FastAPI returns 422.

Source

Thrown at private_gpt/chat/schema_models.py:102

def _validate_json_schema_item(schema: dict[str, Any], strict: bool = True) -> None:
    """Validate that the schema is a valid JSON Schema object."""
    if not isinstance(schema, dict):
        raise ValueError("Schema must be a dictionary representing JSON Schema")

    if schema == {}:
        return

    # Handle combinators first
    if "oneOf" in schema:
        if not isinstance(schema["oneOf"], list):
            raise ValueError("'oneOf' must be an array of schemas")
        for sub_schema in schema["oneOf"]:
            _validate_json_schema_item(sub_schema, strict=False)
        return  # oneOf schemas don't need type field

    if "anyOf" in schema:
        if not isinstance(schema["anyOf"], list):
            raise ValueError("'anyOf' must be an array of schemas")
        for sub_schema in schema["anyOf"]:
            _validate_json_schema_item(sub_schema, strict=False)
        return  # anyOf schemas don't need type field

    if "allOf" in schema:
        if not isinstance(schema["allOf"], list):
            raise ValueError("'allOf' must be an array of schemas")
        for sub_schema in schema["allOf"]:
            _validate_json_schema_item(sub_schema, strict=False)
        return  # allOf schemas don't need type field

    # Regular schema validation
    if "type" not in schema:
        if strict:
            raise ValueError("Schema must define a 'type' field")
        else:
            return  # Non-strict mode allows missing type

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Normalize with posix semantics: PurePosixPath(*Path(p).parts).as_posix() or p.replace('\\', '/').
  2. Build paths with '/' literals or pathlib's as_posix(), never raw os.path.join output.
  3. Validate client-side that path matches ^[^\\]+$ before submit.

Example fix

# before
{"path": "assets\\logo.png", "content_base64": "..."}

# after
from pathlib import PurePosixPath, Path
path = PurePosixPath(*Path(raw).parts).as_posix()  # 'assets/logo.png'
{"path": path, "content_base64": "..."}
Defensive patterns

Strategy: validation

Validate before calling

const path = String(rawPath).replace(/\\/g, '/');
if (rawPath.includes('\\')) warn('normalized backslashes for skill path');

Type guard

const usesPosixSeparators = (p) => typeof p === 'string' && !p.includes('\\');

Prevention

When it happens

Trigger: Submitting a skill file entry with path 'assets\\logo.png' — typically produced on Windows clients or by code using os.path.join and then serializing without normalization.

Common situations: Windows developer machines; Python scripts building paths with os.path.join and passing them verbatim; log/config files containing backslash-separated paths.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/66602917017bb12c. Report an issue: GitHub.