headroomlabs-ai/headroom · error · ValueError
max_sessions must be > 0
Error message
max_sessions must be > 0
What it means
SessionCcrTracker is a bounded LRU keyed by (provider, session_id) that records which sessions have already done context-clone reuse (CCR). Its constructor validates max_sessions > 0 because an OrderedDict-based bound of 0 or negative would evict every entry immediately or misbehave. This is a direct-constructor guard; from configuration the value normally arrives via resolve_beta_tracker_max_sessions() (see the HEADROOM_BETA_TRACKER_MAX_SESSIONS errors).
Source
Thrown at headroom/proxy/ccr_session_tracker.py:14
"""Session-scoped state for sticky CCR retrieval tool injection."""
from __future__ import annotations
import threading
from collections import OrderedDict
class SessionCcrTracker:
"""Bounded LRU tracker recording per-provider/session CCR state."""
def __init__(self, max_sessions: int) -> None:
if max_sessions <= 0:
raise ValueError("max_sessions must be > 0")
self._max_sessions = max_sessions
self._lock = threading.RLock()
self._sessions: OrderedDict[tuple[str, str], tuple[bool, bytes | None]] = OrderedDict()
@property
def active_sessions(self) -> int:
with self._lock:
return len(self._sessions)
def _key(self, provider: str, session_id: str) -> tuple[str, str]:
return (provider, session_id)
def has_done_ccr(self, provider: str, session_id: str) -> bool:
"""Return True when this session has previously performed CCR."""
if not provider:
raise ValueError("provider must be non-empty")
if not session_id:View on GitHub (pinned to 322425c43b)
Solutions
- Pass a positive bound: SessionCcrTracker(max_sessions=1000).
- If the value is computed, clamp or validate it before construction: max(1, computed).
- Route user-supplied values through resolve_beta_tracker_max_sessions() so they get the same validation and default.
Example fix
# before tracker = SessionCcrTracker(max_sessions=0) # after tracker = SessionCcrTracker(max_sessions=1) # minimum valid bound
Defensive patterns
Strategy: validation
Validate before calling
def make_tracker(max_sessions: int | None) -> SessionCcrTracker:
return SessionCcrTracker(max_sessions=1000 if not max_sessions or max_sessions <= 0 else max_sessions) Type guard
def valid_bound(value: object) -> bool:
return isinstance(value, int) and value > 0 Try / catch
try:
tracker = SessionCcrTracker(max_sessions=bound)
except ValueError:
bound = 1000
tracker = SessionCcrTracker(max_sessions=bound) # log the substitution Prevention
- Validate numeric config at the edges of your system (CLI/env parse), not at object construction deep in libraries.
- Property-test constructors with generated ints to catch boundary assumptions.
When it happens
Trigger: Calling SessionCcrTracker(max_sessions=0) or with a negative int in code or tests — typically when computing the bound from a config value, len() of an empty collection, or a subtraction that underflows.
Common situations: Test fixtures passing 0 to keep the tracker 'off'; deriving max_sessions from another quantity (e.g. max_total - reserved) that can legitimately reach 0; wiring an env-configured value straight into the constructor without the resolver's validation.
Related errors
- max_sessions must be > 0
- items_json must be JSON: {e}
- doc_json must be JSON: {e}
- target_savings must be between 0 and 1
- position must be one of {POSITIONS}, got {position!r}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/0140aaf20aecf631.
Report an issue: GitHub.