rohitg00/ai-engineering-from-scratch · error · ValueError
schema type for {location} must be a string or non-empty str
Error message
schema type for {location} must be a string or non-empty string list What it means
_validate_schema_value raises ValueError(f'schema type for {location} must be a string or non-empty string list') when the 'type' keyword of a (sub)schema is neither a string nor a non-empty list of strings - e.g. an int, bool, None, empty list, or a list containing non-strings. The validator supports scalar types and type arrays and rejects anything else as an authoring error in the schema itself.
Source
Thrown at certifications/claude/lessons/10-tool-use-and-agentic-loops/code/main.py:116
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:
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"),
):View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Set 'type' to a single supported string or a non-empty list of supported strings.
- Read the {location} in the message to find which subschema has the bad type keyword.
- Lint generated schemas: assert type fields are str or a non-empty list[str] before use.
- When templating schemas, omit the type key rather than writing null.
Example fix
# before
{"type": []}
# ValueError: schema type for $.x must be a string or non-empty string list
# after
{"type": ["string", "integer"]} Defensive patterns
Strategy: type-guard
Validate before calling
def type_keyword_ok(schema: dict) -> bool:
t = schema.get("type")
if t is None:
return True
if isinstance(t, str):
return True
return isinstance(t, list) and len(t) > 0 and all(isinstance(x, str) for x in t) Type guard
def is_valid_type_keyword(t) -> bool:
if isinstance(t, str):
return True
return isinstance(t, list) and bool(t) and all(isinstance(x, str) for x in t) Try / catch
try:
validate_tool_input(value, schema)
except ValueError as exc:
if "string or non-empty string list" in str(exc):
raise SchemaError(f"fix the schema: {exc}") from exc
raise Prevention
- Write 'type' as a plain string unless union types are truly needed.
- When templating, omit the type key rather than writing null or empty lists.
- Unit-test schema construction so computed types never leak non-strings.
When it happens
Trigger: Schemas such as {"type": 1}, {"type": null}, {"type": []}, {"type": ["string", 2]}, or lists containing unsupported entries. Triggered at the root schema and recursively at any properties/items location named in the message.
Common situations: Programmatic schema builders inserting computed types that yield None; YAML configs where 'type' is parsed as a non-string; partial refactors from scalar types to type lists leaving empty arrays.
Related errors
- unsupported schema type: {expected}
- schema {name} must be a non-negative integer
- schema for {location} must be an object
- invalid type for {location}: expected {expected}
- schema enum for {location} must be a non-empty list
AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26).
Data as JSON: /api/errors/85507d0f44c75db0.
Report an issue: GitHub.