headroomlabs-ai/headroom · error · ValueError

Unknown CLI model: {model}

Error message

Unknown CLI model: {model}

What it means

Raised in _call_cli_backend (analyzer.py:574) when the *model identifier* passed to the CLI execution path does not match any model_name in _CLI_BACKENDS. This is an internal-consistency ValueError: model resolution should only ever hand this function one of the registered CLI model ids (e.g. claude-cli), so hitting it means a mismatched model string was routed to the CLI code path.

Source

Thrown at headroom/learn/analyzer.py:574

    Args:
        digest: Token-efficient session digest to analyze.
        model: CLI model identifier (e.g. ``claude-cli``).

    Returns:
        Parsed JSON recommendations from the CLI tool.

    Raises:
        ValueError: If *model* is not a known CLI backend.
        RuntimeError: If the CLI is not installed, exits non-zero, or times out.
    """
    cmd: list[str] | None = None
    for _name, model_name, cmd_parts in _CLI_BACKENDS:
        if model_name == model:
            cmd = cmd_parts
            break
    if cmd is None:
        raise ValueError(f"Unknown CLI model: {model}")

    prompt = _SYSTEM_PROMPT + "\n\n" + _USER_PROMPT_PREFIX + digest
    hard_cap = _resolve_timeout_secs("HEADROOM_LEARN_CLI_TIMEOUT_SECS", _CLI_TIMEOUT)

    if model == "claude-cli":
        idle_cap = _resolve_timeout_secs("HEADROOM_LEARN_CLI_IDLE_TIMEOUT_SECS", _CLI_IDLE_TIMEOUT)
        return _call_claude_cli_streaming(cmd, prompt, hard_cap=hard_cap, idle_cap=idle_cap)

    try:
        result = run(
            cmd,
            input=prompt,
            capture_output=True,
            text=True,
            timeout=hard_cap,
        )
    except FileNotFoundError:
        shim_cmd = _resolve_windows_cli_shim(cmd)

View on GitHub (pinned to 322425c43b)

Solutions

  1. If you passed --model yourself, either omit it and let HEADROOM_LEARN_CLI pick the backend, or pass an API-backed LiteLLM model name and remove HEADROOM_LEARN_CLI
  2. If calling the helper programmatically, pass one of the registered CLI model ids (inspect _CLI_BACKENDS for exact names)
  3. Upgrade/align headroom to one consistent version so the backend registry matches the resolver

Example fix

# before
HEADROOM_LEARN_CLI=claude headroom learn --model gpt-4o  # model routed to CLI path

# after
HEADROOM_LEARN_CLI=claude headroom learn  # CLI backend picks its own model
Defensive patterns

Strategy: validation

Validate before calling

import os
CLI_MODELS = {m for _n, m, _c in _CLI_BACKENDS}  # if calling internals
if custom_model is not None and custom_model not in CLI_MODELS and not custom_model.startswith(('gpt-', 'claude-', 'gemini-')):
    raise SystemExit('Pass a registered CLI model or an API model name')

Try / catch

try:
    recs = _call_cli_backend(model, digest)
except ValueError as e:
    if 'Unknown CLI model' in str(e):
        recs = _call_api_backend(model, digest)  # route to LiteLLM instead
    else:
        raise

Prevention

When it happens

Trigger: Calling the CLI-invocation helper directly with an arbitrary model string; or a code path where an API model (like gpt-4o) is mistakenly passed to the CLI branch instead of the LiteLLM branch — e.g. custom code that wraps headroom learn's internals, or HEADROOM_LEARN_CLI selecting a backend while --model names a different, non-CLI model.

Common situations: Users calling private analyzer helpers in their own scripts; inconsistent flags combining --model with HEADROOM_LEARN_CLI; headroom version skew where the _CLI_BACKENDS registry was renamed between releases.

Related errors


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