headroomlabs-ai/headroom · error · ValueError
workers must be >= 1
Error message
workers must be >= 1
What it means
run_server validates that the worker process count is at least 1; workers < 1 (0 or negative) is rejected with ValueError before configuration is finalized. Worker count maps onto ProxyConfig.worker_processes, which itself must be >= 1.
Source
Thrown at headroom/proxy/server.py:5263
still gets the banner since it has no other startup output.
"""
if not FASTAPI_AVAILABLE:
print("ERROR: FastAPI required. Install: pip install fastapi uvicorn httpx")
sys.exit(1)
# Seed the request-time coding-profile toggles (tool-search, dedupe, read
# protection, lossless→lossy, effort-router, block-char floor) into the
# process env before serving, so downstream per-request readers pick them up.
# Done here (not in the CLI command) so unit tests that mock run_server never
# mutate os.environ. setdefault → explicit env still wins. MODE / profile are
# already resolved into `config` above via their inline defaults.
from headroom.agent_savings import seed_proxy_env_defaults
seed_proxy_env_defaults()
config = config or ProxyConfig()
if workers < 1:
raise ValueError("workers must be >= 1")
config.worker_processes = workers
code_aware_status = _get_code_aware_banner_status(config)
# Format connection pool info
pool_info = f"max={config.max_connections}, keepalive={config.max_keepalive_connections}"
http2_status = "ENABLED" if (config.http2 and not config.http_proxy) else "DISABLED"
backend_status = format_backend_status(
backend=config.backend,
anyllm_provider=config.anyllm_provider,
bedrock_region=config.bedrock_region,
)
# Resolve upstream API targets for display in the banner (#583).
api_targets = resolve_api_targets(config.provider_api_overrides)
if print_banner:
print(f"""View on GitHub (pinned to 322425c43b)
Solutions
- Pass workers=1 for single-process serving.
- Clamp computed worker counts with max(1, computed).
- Validate CLI/env worker inputs to IntRange(min=1)-style bounds.
Example fix
# before run_server(config=config, workers=max(0, os.cpu_count() - 8)) # after run_server(config=config, workers=max(1, os.cpu_count() - 8))
Defensive patterns
Strategy: validation
Validate before calling
workers = max(1, int(os.environ.get("HEADROOM_WORKERS", "1")))
if workers < 1:
raise SystemExit("workers must be >= 1") Type guard
def valid_workers(n: int) -> bool:
return isinstance(n, int) and n >= 1 Try / catch
try:
run_server(config=config, workers=workers)
except ValueError as e:
if "workers" in str(e):
run_server(config=config, workers=1)
else:
raise Prevention
- Clamp auto-computed worker counts with max(1, n).
- Use 1 for single-process; never 0.
When it happens
Trigger: Calling run_server(workers=0) or run_server(workers=-1); computing workers from an expression like len(tasks)-1 that can go negative; CLI flags accepting 0.
Common situations: Auto-sizing workers from CPU/load formulas that return 0; passing a CLI --workers 0 expecting single-process mode; config templating with an unset variable defaulting to 0.
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/699bf11101e8ba5b.
Report an issue: GitHub.