headroomlabs-ai/headroom · error · RuntimeError
`{' '.join(cmd)}` exceeded the {hard_cap}s hard cap. Raise H
Error message
`{' '.join(cmd)}` exceeded the {hard_cap}s hard cap. Raise HEADROOM_LEARN_CLI_TIMEOUT_SECS for slower networks or larger digests, or try a different backend with --model <litellm-model-name>. What it means
Raised in the streaming claude-cli watchdog loop: every iteration checks elapsed = time.monotonic() - start against hard_cap, and once the total runtime exceeds it, the child process is killed via _kill() and this RuntimeError is raised. Unlike the idle cap (last-activity based, handled separately), the hard cap bounds TOTAL wall-clock time regardless of streaming progress; default 300s via HEADROOM_LEARN_CLI_TIMEOUT_SECS.
Source
Thrown at headroom/learn/analyzer.py:720
stderr_lines: list[str] = []
final_result: str | None = None
eofs = 0
def _kill(reason: str) -> None:
proc.kill()
try:
proc.wait(timeout=5)
except (
subprocess.TimeoutExpired
): # pragma: no cover — defensive, kill normally returns fast
pass
logger.debug("claude-cli killed: %s", reason)
while eofs < 2:
elapsed = time.monotonic() - start
if elapsed > hard_cap:
_kill(f"hard cap {hard_cap}s exceeded")
raise RuntimeError(
f"`{' '.join(cmd)}` exceeded the {hard_cap}s hard cap. "
"Raise HEADROOM_LEARN_CLI_TIMEOUT_SECS for slower networks or "
"larger digests, or try a different backend with "
"--model <litellm-model-name>."
)
idle_elapsed = time.monotonic() - last_activity
if idle_elapsed > idle_cap:
_kill(f"idle cap {idle_cap}s exceeded")
raise RuntimeError(
f"`{' '.join(cmd)}` produced no output for {idle_cap}s. "
"Check network connectivity, raise "
"HEADROOM_LEARN_CLI_IDLE_TIMEOUT_SECS, or try a different "
"backend with --model <litellm-model-name>."
)
# Block up to 1s waiting for the next event, then re-check deadlines.
try:
tag, line = events.get(timeout=1.0)View on GitHub (pinned to 322425c43b)
Solutions
- Raise the total cap: export HEADROOM_LEARN_CLI_TIMEOUT_SECS=900 (or more)
- Reduce digest size / analyze shorter sessions if the run is legitimately huge
- Diagnose whether the CLI is actually progressing (watch its stream events in debug logs) — if hung, fix network/auth rather than raising the cap
- Switch to an API backend which has no CLI watchdog: headroom learn --model <litellm-model-name>
Example fix
# before headroom learn # streaming claude-cli killed: hard cap 300s exceeded # after export HEADROOM_LEARN_CLI_TIMEOUT_SECS=1200 headroom learn
Defensive patterns
Strategy: retry
Validate before calling
import os
default_cap = 300
if int(os.environ.get('HEADROOM_LEARN_CLI_TIMEOUT_SECS', default_cap)) < estimated_run_secs:
os.environ['HEADROOM_LEARN_CLI_TIMEOUT_SECS'] = str(estimated_run_secs * 2) Try / catch
try:
recs = run_learn()
except RuntimeError as e:
if 'exceeded the' in str(e) and 'hard cap' in str(e):
os.environ['HEADROOM_LEARN_CLI_TIMEOUT_SECS'] = str(int(os.environ.get('HEADROOM_LEARN_CLI_TIMEOUT_SECS', '300')) * 2)
recs = run_learn()
else:
raise Prevention
- Pre-set HEADROOM_LEARN_CLI_TIMEOUT_SECS proportional to digest size
- Watch stream events in debug logs to distinguish slow progress from a hang
- If the CLI streams steadily but still exceeds totals, shrink the digest or switch to an API backend
When it happens
Trigger: `headroom learn` streaming a large digest through claude-cli that legitimately needs more than the cap (or hangs while still trickling output — the idle cap won't fire if lines keep arriving, so the hard cap is the last resort).
Common situations: Very large session digests with default 300s; slow networks/proxies; a previously-set low HEADROOM_LEARN_CLI_TIMEOUT_SECS lingering in the environment; the CLI rate-limited but emitting keep-alive events that defeat the idle watchdog.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- `{' '.join(cmd)}` did not respond within {hard_cap}s. Check
- native detect_content_type exceeded {timeout:.1f}s watchdog
- recommendations IO error at {path}: {source}
- bedrock_eventstream_parse_failed
- bedrock_eventstream_crc_mismatch
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/3cbe91ef544252e2.
Report an issue: GitHub.