headroomlabs-ai/headroom · error · ValueError
rate_limit_requests_per_minute must be >= 1 when rate_limit_
Error message
rate_limit_requests_per_minute must be >= 1 when rate_limit_enabled=True
What it means
ProxyConfig rejects rate limiting enabled with a requests-per-minute value below 1. A zero or negative limit would divide by zero in the token-bucket wait computation and cause 500s on every request, so configuration fails fast. Only configurations with rate_limit_enabled=True are affected.
Source
Thrown at headroom/proxy/models.py:527
def __post_init__(self, smart_routing: bool | None = None) -> None:
if self.rollout is None:
self.rollout = resolve_rollout()
# ``read_maturation`` remains a concrete, already-resolved runtime
# setting for programmatic/config-file callers. The CLI composition
# root derives it from this same snapshot before constructing the
# config; rewriting it here would resolve policy a second time and
# break explicit non-CLI configuration.
if self.worker_processes < 1:
raise ValueError("worker_processes must be >= 1")
if self.retry_enabled and self.retry_max_attempts < 1:
raise ValueError("retry_max_attempts must be >= 1 when retry_enabled=True")
# A 0 (or negative) requests-per-minute limit divides by zero in the
# token-bucket wait computation (rate_limit_policy.consume_from_bucket),
# 500-ing every request. The CLI already guards this with IntRange(min=1);
# fail fast here too so the JSON/programmatic config paths can't produce a
# limiter that crashes at request time. Only matters when limiting is on.
if self.rate_limit_enabled and self.rate_limit_requests_per_minute < 1:
raise ValueError(
"rate_limit_requests_per_minute must be >= 1 when rate_limit_enabled=True"
)
@property
def provider_api_overrides(self) -> ProviderApiOverrides:
"""Return provider API URL overrides as a dedicated provider config object."""
return ProviderApiOverrides(
anthropic=self.anthropic_api_url,
openai=self.openai_api_url,
gemini=self.gemini_api_url,
cloudcode=self.cloudcode_api_url,
vertex=self.vertex_api_url,
)
View on GitHub (pinned to 322425c43b)
Solutions
- Set rate_limit_requests_per_minute to a positive integer such as 60.
- Set rate_limit_enabled=False if no limiting is intended.
- Treat 0 as invalid, not 'unlimited', when generating configs.
Example fix
# before ProxyConfig(rate_limit_enabled=True, rate_limit_requests_per_minute=0) # after ProxyConfig(rate_limit_enabled=True, rate_limit_requests_per_minute=60)
Defensive patterns
Strategy: validation
Validate before calling
def check_rate_limit(cfg):
if cfg.get("rate_limit_enabled", False) and cfg.get("rate_limit_requests_per_minute", 0) < 1:
raise SystemExit("rate_limit_requests_per_minute must be >= 1") Type guard
def valid_rate_limit(cfg) -> bool:
return not cfg.rate_limit_enabled or cfg.rate_limit_requests_per_minute >= 1 Try / catch
try:
ProxyConfig(**raw)
except ValueError as e:
fail_config(e) Prevention
- Treat 0 rpm as invalid, not unlimited.
- Mirror the CLI's min=1 constraint in config generators.
When it happens
Trigger: ProxyConfig(rate_limit_enabled=True, rate_limit_requests_per_minute=0) (or a negative value), typically from a JSON/programmatic config, because the CLI path already enforces a minimum.
Common situations: Setting an env/config flag to enable rate limiting without providing a numeric limit; generating config from templates where 0 means 'unlimited'; CLI bypass via direct config-file use.
Related errors
- Unknown provider: {self.provider}
- api_key is required for cloud mode
- 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
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/a5eff8404fc223c9.
Report an issue: GitHub.