headroomlabs-ai/headroom · error · ValueError

must be <= {field.maximum}

Error message

must be <= {field.maximum}

What it means

ValueError from _coerce in headroom/settings_store.py when a numeric field's coerced value exceeds the field's declared maximum (field.maximum, checked at line 789). The message states the exact ceiling; the error is reported per-field through SettingsValidationError.field_errors.

Source

Thrown at headroom/settings_store.py:789

        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:
                parsed = json.loads(str(value))
            except (ValueError, TypeError) as exc:

View on GitHub (pinned to 322425c43b)

Solutions

  1. Lower the value to at most the maximum stated in the message.
  2. Check for unit mismatch (seconds vs milliseconds) that inflated the number.
  3. Read the field's help text via the settings registry if the cap seems arbitrary.

Example fix

# before
save({'port': 70000})  # ValueError: must be <= 65535

# after
save({'port': 65535})
Defensive patterns

Strategy: validation

Validate before calling

from headroom.settings_store import _BY_KEY

def not_above_max(key: str, v: int | float) -> bool:
    f = _BY_KEY.get(key)
    return f is None or f.maximum is None or v <= f.maximum

Try / catch

except SettingsValidationError as e:
    for key, msg in e.field_errors.items():
        if 'must be <=' in msg:
            payload[key] = min(payload[key], _BY_KEY[key].maximum)
    store.save(payload)

Prevention

When it happens

Trigger: save({'port': 70000}) for a port field with maximum=65535; raising max_tokens above the model's documented cap; percentage fields set to 150 when maximum=100.

Common situations: Users typing oversized numbers into unbounded inputs; migrating configs tuned for a bigger model/deployment; unit confusion (ms vs s) inflating a value past the cap.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/c9536a9593d0d140. Report an issue: GitHub.