headroomlabs-ai/headroom · critical · RuntimeError

No LLM API key found. headroom learn needs one of: export

Error message

No LLM API key found. headroom learn needs one of:
  export ANTHROPIC_API_KEY=sk-ant-...   → uses claude-sonnet-4-6
  export OPENAI_API_KEY=sk-...          → uses gpt-4o
  export GEMINI_API_KEY=...             → uses gemini-flash-latest
Or set HEADROOM_LEARN_CLI to a coding agent CLI (claude, gemini, codex).
Or install one of those CLIs for auto-detection.
Or specify a model directly: headroom learn --model <litellm-model-name>

What it means

Terminal failure of backend resolution for `headroom learn`: no API-key env var is set (step 1), no valid HEADROOM_LEARN_CLI override exists (step 2), and shutil.which found none of the auto-detectable coding-agent CLIs on PATH (step 3). The RuntimeError enumerates every escape hatch: three API-key env vars, the HEADROOM_LEARN_CLI override, CLI auto-detection, or --model with a LiteLLM model name.

Source

Thrown at headroom/learn/analyzer.py:148

    # 2. Explicit CLI selection via environment variable
    cli_override = os.environ.get("HEADROOM_LEARN_CLI")
    if cli_override:
        for cli_name, model, _cmd in _CLI_BACKENDS:
            if cli_name == cli_override:
                logger.info("HEADROOM_LEARN_CLI=%s — using %s CLI backend", cli_override, cli_name)
                return model
        valid = ", ".join(name for name, _, _ in _CLI_BACKENDS)
        raise ValueError(
            f"HEADROOM_LEARN_CLI={cli_override!r} is not a supported CLI. Valid values: {valid}"
        )

    # 3. Auto-detect installed CLI tools
    for cli_name, model, _cmd in _CLI_BACKENDS:
        if shutil.which(cli_name):
            logger.info("No API key found — auto-detected %s CLI as LLM backend", cli_name)
            return model

    raise RuntimeError(
        "No LLM API key found. headroom learn needs one of:\n"
        "  export ANTHROPIC_API_KEY=sk-ant-...   → uses claude-sonnet-4-6\n"
        "  export OPENAI_API_KEY=sk-...          → uses gpt-4o\n"
        "  export GEMINI_API_KEY=...             → uses gemini-flash-latest\n"
        "Or set HEADROOM_LEARN_CLI to a coding agent CLI (claude, gemini, codex).\n"
        "Or install one of those CLIs for auto-detection.\n"
        "Or specify a model directly: headroom learn --model <litellm-model-name>"
    )


class SessionAnalyzer:
    """Analyzes session data via LLM to produce actionable recommendations.

    Uses LiteLLM for provider-agnostic access to 100+ models.
    Auto-detects the best available model from environment API keys.
    """

    def __init__(self, model: str | None = None):

View on GitHub (pinned to 322425c43b)

Solutions

  1. Export an API key: export ANTHROPIC_API_KEY=sk-ant-... (or OPENAI_API_KEY / GEMINI_API_KEY)
  2. Or install one of the coding-agent CLIs and ensure it's on PATH (verify with `which claude`)
  3. Or point at a backend explicitly: export HEADROOM_LEARN_CLI=claude (valid values only)
  4. Or bypass resolution entirely: headroom learn --model <litellm-model-name> with the matching key exported

Example fix

# before
headroom learn  # RuntimeError: No LLM API key found

# after
export ANTHROPIC_API_KEY=sk-ant-...
headroom learn
Defensive patterns

Strategy: validation

Validate before calling

import os, shutil
ok = any(os.environ.get(k) for k in ('ANTHROPIC_API_KEY', 'OPENAI_API_KEY', 'GEMINI_API_KEY')) \
     or os.environ.get('HEADROOM_LEARN_CLI') \
     or any(shutil.which(c) for c in ('claude', 'gemini', 'codex'))
if not ok:
    raise SystemExit('headroom learn needs an API key, HEADROOM_LEARN_CLI, an installed CLI, or --model')

Try / catch

try:
    subprocess.run(['headroom', 'learn'], check=True, capture_output=True)
except subprocess.CalledProcessError as e:
    if 'No LLM API key found' in (e.stderr or ''):
        print('Set ANTHROPIC_API_KEY / OPENAI_API_KEY / GEMINI_API_KEY first')
    raise

Prevention

When it happens

Trigger: Running `headroom learn` in a bare environment: no ANTHROPIC_API_KEY/OPENAI_API_KEY/GEMINI_API_KEY, HEADROOM_LEARN_CLI unset or empty, and no claude/gemini/codex binaries discoverable via PATH.

Common situations: Fresh container/CI runner; API keys stored in a .env file that headroom doesn't load; CLI installed via a version manager (nvm, volta) whose bin dir isn't on PATH in this shell; keys set in a different shell session or systemd unit.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/fb0f486866049b4e. Report an issue: GitHub.