rohitg00/ai-engineering-from-scratch · error · ValueError
schema {name} must be a non-negative integer
Error message
schema {name} must be a non-negative integer What it means
_integer_bound raises ValueError(f'schema {name} must be a non-negative integer') when a numeric constraint keyword (minimum or maximum) is present but its value is not an int, is a bool, or is negative. The function reads bounds for numeric comparisons; a malformed bound cannot be compared safely, so it fails fast. This is about the schema author's constraint value, not the data being validated.
Source
Thrown at certifications/claude/lessons/10-tool-use-and-agentic-loops/code/main.py:104
"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:
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"]View on GitHub (pinned to 39ea8a1c6d)
Solutions
- Make the bound a plain non-negative int literal: {"minimum": 1, "maximum": 5}.
- Coerce config-sourced bounds with int() (and range-check) before building the schema.
- Add a schema-lint step that verifies minimum/maximum are non-negative ints at startup.
- If fractional bounds are genuinely needed, note this validator subset only supports integer bounds and adjust the design.
Example fix
# before
{"type": "integer", "minimum": "1"}
# ValueError: schema minimum must be a non-negative integer
# after
{"type": "integer", "minimum": 1} Defensive patterns
Strategy: validation
Validate before calling
def bounds_ok(schema: dict) -> bool:
return all(
isinstance(schema.get(k, 0), int) and not isinstance(schema.get(k, 0), bool) and schema.get(k, 0) >= 0
for k in ("minimum", "maximum")
) Type guard
def is_non_negative_int(value) -> bool:
return isinstance(value, int) and not isinstance(value, bool) and value >= 0 Try / catch
try:
validate_tool_input(value, schema)
except ValueError as exc:
if "must be a non-negative integer" in str(exc):
schema = normalize_bounds(schema) # coerce "1"->1, 1.0->1 at config load
validate_tool_input(value, schema)
else:
raise Prevention
- Coerce config/YAML/env-sourced bounds with int() before building schemas.
- Never use booleans or floats for minimum/maximum in this validator.
- Assert 0 <= minimum <= maximum at schema build time.
When it happens
Trigger: A schema like {"type": "integer", "minimum": "1"} (string bound), {"minimum": true} (bool), {"minimum": -1} (negative), or {"maximum": 2.5} (float). Reached whenever _validate_schema_value processes a numeric value and iterates the ('minimum', 'maximum') keyword table.
Common situations: Env-var or YAML config flowing into schema bounds as strings; JSON configs where 1.0 parses as float; placeholder values like "TODO" left in schemas; booleans leaking in from checkbox-driven schema builders.
Related errors
- max_attempts must be positive
- unsupported schema type: {expected}
- 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/3cc4285a5bf4860e.
Report an issue: GitHub.