rohitg00/ai-engineering-from-scratch · error · ValueError

unsupported schema type: {expected}

Error message

unsupported schema type: {expected}

What it means

_matches_json_type raises ValueError(f'unsupported schema type: {expected}') when a schema's declared type string is not one of the supported JSON types (boolean, integer, number, string, array, object). This lesson-scoped mini-validator treats an unsupported type name ('null', 'int', 'str', 'any') as an authoring bug in the schema, not a data problem, and fails fast instead of silently passing.

Source

Thrown at certifications/claude/lessons/10-tool-use-and-agentic-loops/code/main.py:95

        "execution": execution,
        "procedure": "skill" if needs.reusable_procedure else "inline-instructions",
        "execution_boundary": boundary,
        "authorization_owner": "application-policy",
    }


def _matches_json_type(value: Any, expected: str) -> bool:
    checks: dict[str, Callable[[Any], bool]] = {
        "null": lambda item: item is None,
        "boolean": lambda item: isinstance(item, bool),
        "integer": lambda item: isinstance(item, int) and not isinstance(item, bool),
        "number": lambda item: isinstance(item, (int, float)) and not isinstance(item, bool),
        "string": lambda item: isinstance(item, str),
        "array": lambda item: isinstance(item, list),
        "object": lambda item: isinstance(item, dict),
    }
    if expected not in checks:
        raise ValueError(f"unsupported schema type: {expected}")
    return checks[expected](value)


def _integer_bound(schema: dict[str, Any], name: str) -> int | None:
    if name not in schema:
        return None
    value = schema[name]
    if not isinstance(value, int) or isinstance(value, bool) or value < 0:
        raise ValueError(f"schema {name} must be a non-negative integer")
    return value


def _validate_schema_value(value: Any, schema: Any, location: str) -> None:
    if not isinstance(schema, dict):
        raise ValueError(f"schema for {location} must be an object")

    declared_type = schema.get("type")
    if declared_type is not None:

View on GitHub (pinned to 39ea8a1c6d)

Solutions

  1. Replace the unsupported type with a supported one: 'string', 'integer', 'number', 'boolean', 'array', or 'object'.
  2. If unions are needed, use a non-empty type list of supported names rather than unsupported type names.
  3. Add a startup lint that walks the schema and rejects unknown type strings before any model call.
  4. Keep test fixtures to the documented type vocabulary.

Example fix

# before
{"type": "str"}
# ValueError: unsupported schema type: str

# after
{"type": "string"}
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_TYPES = {"boolean", "integer", "number", "string", "array", "object"}
def schema_types_ok(schema: dict) -> bool:
    t = schema.get("type")
    types = t if isinstance(t, list) else [t]
    return all(x in SUPPORTED_TYPES for x in types if x is not None)

Type guard

def is_supported_type_name(name: str) -> bool:
    return name in {"boolean", "integer", "number", "string", "array", "object"}

Try / catch

try:
    validate_tool_input(value, schema)
except ValueError as exc:
    if str(exc).startswith("unsupported schema type"):
        raise SchemaAuthoringError(str(exc)) from exc  # schema bug: fix schema, do not retry
    raise

Prevention

When it happens

Trigger: Validating a tool input_schema whose type is 'null', 'any', 'int', 'str', or misspelled; nesting such a subschema inside properties/items so _validate_schema_value recurses into _matches_json_type; passing a JSON-Schema draft using types this subset never implemented.

Common situations: Translating Python/TypeScript type names into schema types ('str' instead of 'string'); copying full JSON Schema specs that use 'null' or type arrays with unsupported members; hand-writing tool definitions.

Related errors


AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26). Data as JSON: /api/errors/a9656a1d81964c1c. Report an issue: GitHub.