rohitg00/ai-engineering-from-scratch · error · ValueError
schema enum for {location} must be a non-empty list
Error message
schema enum for {location} must be a non-empty list What it means
_validate_schema_value raises ValueError(f'schema enum for {location} must be a non-empty list') when a (sub)schema contains an "enum" keyword whose value is not a list or is an empty list. Like the other schema-shape errors this reports a malformed schema, not bad data: an enum constraint with no choices is meaningless, so the validator refuses it at schema-check time.
Source
Thrown at certifications/claude/lessons/10-tool-use-and-agentic-loops/code/main.py:124
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:
declared_types = declared_type if isinstance(declared_type, list) else [declared_type]
if not declared_types or not all(isinstance(item, str) for item in declared_types):
raise ValueError(f"schema type for {location} must be a string or non-empty string list")
if not any(_matches_json_type(value, item) for item in declared_types):
expected = " or ".join(declared_types)
raise ValueError(f"invalid type for {location}: expected {expected}")
if "enum" in schema:
choices = schema["enum"]
if not isinstance(choices, list) or not choices:
raise ValueError(f"schema enum for {location} must be a non-empty list")
if value not in choices:
raise ValueError(f"invalid value for {location}: not in enum")
if isinstance(value, (int, float)) and not isinstance(value, bool):
for keyword, comparison, message in (
("minimum", lambda current, bound: current >= bound, "below minimum"),
("maximum", lambda current, bound: current <= bound, "above maximum"),
("exclusiveMinimum", lambda current, bound: current > bound, "at or below exclusive minimum"),
("exclusiveMaximum", lambda current, bound: current < bound, "at or above exclusive maximum"),
):
if keyword not in schema:
continue
bound = schema[keyword]
if not isinstance(bound, (int, float)) or isinstance(bound, bool):
raise ValueError(f"schema {keyword} for {location} must be numeric")
if not comparison(value, bound):
raise ValueError(f"invalid value for {location}: {message} {bound}")
View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Write the enum as a non-empty JSON array of allowed values: {"enum": ["low", "medium", "high"]}.
- When generating enums in code, fail loudly or fall back to a default if the source list is empty.
- In YAML configs, always use list syntax even for one item: enum: ["yes"].
- Read {location} in the message to locate the offending subschema.
Example fix
# before
{"type": "string", "enum": "low|medium|high"}
# ValueError: schema enum for $.priority must be a non-empty list
# after
{"type": "string", "enum": ["low", "medium", "high"]} Defensive patterns
Strategy: validation
Validate before calling
def enum_keyword_ok(schema: dict) -> bool:
return "enum" not in schema or (isinstance(schema["enum"], list) and len(schema["enum"]) > 0) Type guard
def is_valid_enum(choices) -> bool:
return isinstance(choices, list) and len(choices) > 0 Try / catch
try:
validate_tool_input(value, schema)
except ValueError as exc:
if "schema enum" in str(exc):
raise SchemaError(f"fix the schema: {exc}") from exc # schema bug, not data bug
raise Prevention
- Always author enums as non-empty JSON arrays, even for a single value.
- Fail loudly when dynamic enum sources (config, API listings) return empty lists.
- In YAML, use explicit list syntax: enum: ["a", "b"].
When it happens
Trigger: Schemas like {"type": "string", "enum": "abc"} (string instead of list), {"enum": []} (empty), or an enum built from a config/API source list that came back empty. Hit at any properties/items location once the type check passes.
Common situations: Generating enums dynamically from a listing that returns nothing; typos like enum: "low|medium|high"; YAML configs where a single-item enum collapses to a scalar.
Related errors
- unsupported schema type: {expected}
- schema {name} must be a non-negative integer
- schema for {location} must be an object
- schema type for {location} must be a string or non-empty str
- invalid type for {location}: expected {expected}
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/7305faa1586c5fa0.
Report an issue: GitHub.