headroomlabs-ai/headroom · error · ValueError
must be >= {field.minimum}
Error message
must be >= {field.minimum} What it means
ValueError from _coerce in headroom/settings_store.py when a numeric field's coerced value is below the field's declared minimum (field.minimum, checked at line 787). Each SettingField in the SETTINGS registry declares its own bounds; the message includes the exact bound. Surfaces via SettingsValidationError.field_errors under the field key.
Source
Thrown at headroom/settings_store.py:787
if token in ("1", "true", "yes", "on"):
return True
if token in ("0", "false", "no", "off", ""):
return False
raise ValueError(f"expected a boolean, got {value!r}")
if field.type in ("int", "float"):
if isinstance(value, bool): # bool is an int subclass — reject explicitly
raise ValueError(f"expected a number, got {value!r}")
number: int | float
if field.type == "int":
if isinstance(value, float) and not value.is_integer():
raise ValueError(f"expected an integer, got {value!r}")
number = int(value)
else:
number = float(value)
if not math.isfinite(number):
raise ValueError(f"expected a finite number, got {value!r}")
if field.minimum is not None and number < field.minimum:
raise ValueError(f"must be >= {field.minimum}")
if field.maximum is not None and number > field.maximum:
raise ValueError(f"must be <= {field.maximum}")
return number
if field.type == "enum":
token = str(value)
if token not in field.choices:
raise ValueError(f"{token!r} not one of {list(field.choices)}")
return token
if field.type == "csv-list":
tokens = value if isinstance(value, list | tuple) else str(value).split(",")
tokens = [str(token).strip() for token in tokens]
tokens = [token for token in tokens if token]
return ",".join(tokens) if tokens else None
if field.type == "header-map":
if isinstance(value, dict):
parsed = value
else:
try:View on GitHub (pinned to 322425c43b)
Solutions
- Raise the value to at least the minimum stated in the error message.
- Check the field's declared minimum in headroom.settings_store.SETTINGS to know the allowed range.
- If the bound feels wrong for your use, open an issue or use a different field rather than fighting validation.
Example fix
# before
save({'max_retries': -1}) # ValueError: must be >= 0
# after
save({'max_retries': 0}) Defensive patterns
Strategy: validation
Validate before calling
from headroom.settings_store import _BY_KEY
def within_bounds(key: str, v: int | float) -> bool:
f = _BY_KEY.get(key)
return f is None or f.minimum is None or v >= f.minimum Type guard
def in_range(key: str, v) -> bool:
f = _BY_KEY.get(key)
if f is None: return True
if f.minimum is not None and v < f.minimum: return False
if f.maximum is not None and v > f.maximum: return False
return True Try / catch
except SettingsValidationError as e:
for key, msg in e.field_errors.items():
if 'must be >=' in msg:
floor = _BY_KEY[key].minimum
payload[key] = max(payload[key], floor) # clamp
store.save(payload) Prevention
- Set min/max attributes on UI inputs from the field metadata.
- Clamp user-supplied numbers to [minimum, maximum] before save.
When it happens
Trigger: save({'max_tokens': 0}) when the field declares minimum=1; setting a timeout to 0 or a negative retry count; decrementing a setting in a loop until it crosses the floor.
Common situations: Scripts clamping values with the wrong comparison (>= vs >); porting configs from an older version where the minimum was lowered/raised; UI number inputs without min attributes letting users type 0.
Related errors
- must be <= {field.maximum}
- expected a boolean, got {value!r}
- expected a number, got {value!r}
- expected an integer, got {value!r}
- expected a finite number, got {value!r}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/039f5e6d4d637eb3.
Report an issue: GitHub.