headroomlabs-ai/headroom · error · ValueError
target_savings must be between 0 and 1
Error message
target_savings must be between 0 and 1
What it means
with_target_savings rejects any target_savings outside the open interval (0, 1). The check is strict (0 < x < 1), so exactly 0 or exactly 1 are also rejected, because a 0% or 100% savings target produces a degenerate target_ratio (1.0 or 0.0) that downstream budget math cannot use meaningfully.
Source
Thrown at headroom/agent_savings.py:380
Deliberately NOT called from ``_proxy_config_from_env`` / ``ContentRouter`` or
any other library-level builder that unit tests construct directly, so those
keep clean (unseeded) defaults and test isolation is preserved.
"""
target = os.environ if env is None else env
# apply_agent_savings_env_defaults honors an explicit HEADROOM_SAVINGS_PROFILE
# already in the env and otherwise falls back to DEFAULT_PROFILE (coding).
apply_agent_savings_env_defaults(target)
def with_target_savings(
profile: AgentSavingsProfile,
target_savings: float,
) -> AgentSavingsProfile:
"""Return a copy of ``profile`` adjusted to a specific savings target."""
if not 0 < target_savings < 1:
raise ValueError("target_savings must be between 0 and 1")
return replace(
profile,
target_savings=target_savings,
target_ratio=round(1 - target_savings, 4),
)
View on GitHub (pinned to 322425c43b)
Solutions
- Pass a fraction strictly between 0 and 1: 0.5 means 50% savings.
- If your input is a percentage, divide by 100 and clamp to the open interval before calling: max(min(pct/100, 0.999), 0.001).
- If you genuinely need 'no savings' or 'full savings', pick a boundary-adjacent value (e.g. 0.0001) or bypass this helper, since the function intentionally forbids the exact endpoints.
Example fix
# before profile = with_target_savings(profile, float(os.environ["SAVINGS_PCT"])) # 75 -> ValueError # after pct = float(os.environ["SAVINGS_PCT"]) / 100 profile = with_target_savings(profile, min(max(pct, 0.001), 0.999))
Defensive patterns
Strategy: validation
Validate before calling
def _clamp_target_savings(value: float) -> float:
"""Coerce to the open interval (0, 1) required by with_target_savings."""
if not 0 < value < 1:
raise ValueError(f"target_savings={value!r} must be in the open interval (0, 1)")
return value
# use before the call:
target = float(os.environ.get("HEADROOM_SAVINGS", "0.5")) / 100 if float(os.environ.get("HEADROOM_SAVINGS", "50")) > 1 else float(os.environ.get("HEADROOM_SAVINGS", "0.5"))
_clamp_target_savings(target) Type guard
def is_valid_target_savings(x: object) -> bool:
return isinstance(x, (int, float)) and not isinstance(x, bool) and 0 < x < 1 Try / catch
try:
profile = with_target_savings(profile, target)
except ValueError as e:
if "target_savings" in str(e):
raise SystemExit(f"--savings must be a fraction in (0,1), got {target!r}; did you mean {target/100}?" )
raise Prevention
- Document the parameter as a fraction, never a percentage, at every CLI/env boundary.
- Validate at the config-parsing layer so the deep helper never sees garbage.
- Remember the interval is open: 0 and 1 are invalid by design.
When it happens
Trigger: Calling with_target_savings(profile, 0.0), with_target_savings(profile, 1.0), a negative value, or a value greater than 1. Values like 0.05 or 0.95 are fine.
Common situations: Computing target_savings from a CLI flag or env var without bounds-checking ('--savings 100' meaning 100 percent instead of 1.0), integer division yielding 0, or treating the parameter as inclusive 0..=1.
Related errors
- default_importance must be 0.0-1.0, got {self.default_import
- dedup_similarity_threshold must be 0.0-1.0, got {self.dedup_
- vector_dimension must be positive, got {self.vector_dimensio
- hnsw_ef_construction must be positive, got {self.hnsw_ef_con
- hnsw_m must be positive, got {self.hnsw_m}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/5d27c7bec4e83294.
Report an issue: GitHub.