{"record":{"id":"02834d40ba0252e3","repo":"headroomlabs-ai/headroom","slug":"unknown-cli-model-model","errorCode":null,"errorMessage":"Unknown CLI model: {model}","messagePattern":"Unknown CLI model: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/learn/analyzer.py","lineNumber":574,"sourceCode":"\n    Args:\n        digest: Token-efficient session digest to analyze.\n        model: CLI model identifier (e.g. ``claude-cli``).\n\n    Returns:\n        Parsed JSON recommendations from the CLI tool.\n\n    Raises:\n        ValueError: If *model* is not a known CLI backend.\n        RuntimeError: If the CLI is not installed, exits non-zero, or times out.\n    \"\"\"\n    cmd: list[str] | None = None\n    for _name, model_name, cmd_parts in _CLI_BACKENDS:\n        if model_name == model:\n            cmd = cmd_parts\n            break\n    if cmd is None:\n        raise ValueError(f\"Unknown CLI model: {model}\")\n\n    prompt = _SYSTEM_PROMPT + \"\\n\\n\" + _USER_PROMPT_PREFIX + digest\n    hard_cap = _resolve_timeout_secs(\"HEADROOM_LEARN_CLI_TIMEOUT_SECS\", _CLI_TIMEOUT)\n\n    if model == \"claude-cli\":\n        idle_cap = _resolve_timeout_secs(\"HEADROOM_LEARN_CLI_IDLE_TIMEOUT_SECS\", _CLI_IDLE_TIMEOUT)\n        return _call_claude_cli_streaming(cmd, prompt, hard_cap=hard_cap, idle_cap=idle_cap)\n\n    try:\n        result = run(\n            cmd,\n            input=prompt,\n            capture_output=True,\n            text=True,\n            timeout=hard_cap,\n        )\n    except FileNotFoundError:\n        shim_cmd = _resolve_windows_cli_shim(cmd)","sourceCodeStart":556,"sourceCodeEnd":592,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/learn/analyzer.py#L556-L592","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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","If calling the helper programmatically, pass one of the registered CLI model ids (inspect _CLI_BACKENDS for exact names)","Upgrade/align headroom to one consistent version so the backend registry matches the resolver"],"exampleFix":"# before\nHEADROOM_LEARN_CLI=claude headroom learn --model gpt-4o  # model routed to CLI path\n\n# after\nHEADROOM_LEARN_CLI=claude headroom learn  # CLI backend picks its own model","handlingStrategy":"validation","validationCode":"import os\nCLI_MODELS = {m for _n, m, _c in _CLI_BACKENDS}  # if calling internals\nif custom_model is not None and custom_model not in CLI_MODELS and not custom_model.startswith(('gpt-', 'claude-', 'gemini-')):\n    raise SystemExit('Pass a registered CLI model or an API model name')","typeGuard":null,"tryCatchPattern":"try:\n    recs = _call_cli_backend(model, digest)\nexcept ValueError as e:\n    if 'Unknown CLI model' in str(e):\n        recs = _call_api_backend(model, digest)  # route to LiteLLM instead\n    else:\n        raise","preventionTips":["Don't combine --model with HEADROOM_LEARN_CLI; let one mechanism choose the backend","Avoid calling private analyzer helpers directly; prefer the CLI entrypoint","Reproduce backend selection in a unit test after upgrading headroom"],"tags":["internal","model-selection","cli","validation"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}