headroomlabs-ai/headroom · error · ValueError

Invalid {BETA_HEADER_STICKY_ENV}={normalized!r}; expected 'e

Error message

Invalid {BETA_HEADER_STICKY_ENV}={normalized!r}; expected 'enabled' or 'disabled'

What it means

resolve_beta_header_sticky_mode() reads HEADROOM_BETA_HEADER_STICKY and accepts only 'enabled' or 'disabled' (case-insensitive, whitespace-trimmed); empty/unset falls back to the default. Any other value raises ValueError at proxy startup/configuration load time, so a bad value prevents the proxy from starting rather than silently changing beta-header routing behavior.

Source

Thrown at headroom/proxy/beta_header_policy.py:23

from typing import Literal, cast

BETA_HEADER_STICKY_ENV = "HEADROOM_BETA_HEADER_STICKY"
BetaHeaderStickyMode = Literal["enabled", "disabled"]
BETA_HEADER_STICKY_DEFAULT: BetaHeaderStickyMode = "enabled"

BETA_TRACKER_MAX_SESSIONS_ENV = "HEADROOM_BETA_TRACKER_MAX_SESSIONS"
BETA_TRACKER_MAX_SESSIONS_DEFAULT = 1000


def resolve_beta_header_sticky_mode(raw: str | None) -> BetaHeaderStickyMode:
    """Resolve beta-header stickiness mode from an environment value."""

    normalized = (raw or "").strip().lower()
    if not normalized:
        return BETA_HEADER_STICKY_DEFAULT
    if normalized in ("enabled", "disabled"):
        return cast(BetaHeaderStickyMode, normalized)
    raise ValueError(
        f"Invalid {BETA_HEADER_STICKY_ENV}={normalized!r}; expected 'enabled' or 'disabled'"
    )


def resolve_beta_tracker_max_sessions(raw: str | None) -> int:
    """Resolve the positive LRU session bound for beta-header tracking."""

    normalized = (raw or "").strip()
    if not normalized:
        return BETA_TRACKER_MAX_SESSIONS_DEFAULT
    try:
        value = int(normalized)
    except ValueError as exc:
        raise ValueError(
            f"Invalid {BETA_TRACKER_MAX_SESSIONS_ENV}={normalized!r}; expected positive int"
        ) from exc
    if value <= 0:
        raise ValueError(

View on GitHub (pinned to 322425c43b)

Solutions

  1. Use exactly 'enabled' or 'disabled': export HEADROOM_BETA_HEADER_STICKY=enabled (case does not matter).
  2. To get the default behavior, unset the variable entirely rather than setting it to an empty/placeholder value.
  3. Check .env files for quotes or trailing whitespace if the value looks correct — only leading/trailing whitespace is trimmed, embedded characters are not.

Example fix

# before
export HEADROOM_BETA_HEADER_STICKY=true  # ValueError

# after
export HEADROOM_BETA_HEADER_STICKY=enabled
Defensive patterns

Strategy: validation

Validate before calling

def sticky_mode_ok(raw: str | None) -> bool:
    n = (raw or "").strip().lower()
    return not n or n in ("enabled", "disabled")

Type guard

from typing import Literal

BetaStickyMode = Literal["enabled", "disabled"]

def is_sticky_mode(v: str) -> TypeGuard[BetaStickyMode]:
    return v.strip().lower() in ("enabled", "disabled")

Try / catch

try:
    mode = resolve_beta_header_sticky_mode(os.environ.get("HEADROOM_BETA_HEADER_STICKY"))
except ValueError as exc:
    sys.exit(f"config error: {exc}")

Prevention

When it happens

Trigger: Setting HEADROOM_BETA_HEADER_STICKY to anything besides enabled/disabled — e.g. 'true', '1', 'on', 'yes', 'auto', or a stray shell expansion like '' after explicit export.

Common situations: Porting a boolean-style env var from another tool ('true'/'false' are the most common wrong values); copy-pasting a config snippet written for a different env-var dialect; values with invisible characters (quotes from a .env file parsed without quote stripping).

Related errors


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