{"record":{"id":"9294266be954b12d","repo":"headroomlabs-ai/headroom","slug":"headroom-learn-cli-cli-override-r-is-not-a-suppo","errorCode":null,"errorMessage":"HEADROOM_LEARN_CLI={cli_override!r} is not a supported CLI. Valid values: {valid}","messagePattern":"HEADROOM_LEARN_CLI=(.+?) is not a supported CLI\\. Valid values: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/learn/analyzer.py","lineNumber":138,"sourceCode":"      1. API key present → use corresponding LiteLLM model\n      2. HEADROOM_LEARN_CLI env var → use specified CLI backend\n      3. Auto-detect installed CLI tools (claude > gemini > codex)\n      4. Raise RuntimeError with setup instructions\n    \"\"\"\n    # 1. API key detection (existing behavior)\n    for env_var, model in _MODEL_DEFAULTS:\n        if os.environ.get(env_var):\n            return model\n\n    # 2. Explicit CLI selection via environment variable\n    cli_override = os.environ.get(\"HEADROOM_LEARN_CLI\")\n    if cli_override:\n        for cli_name, model, _cmd in _CLI_BACKENDS:\n            if cli_name == cli_override:\n                logger.info(\"HEADROOM_LEARN_CLI=%s — using %s CLI backend\", cli_override, cli_name)\n                return model\n        valid = \", \".join(name for name, _, _ in _CLI_BACKENDS)\n        raise ValueError(\n            f\"HEADROOM_LEARN_CLI={cli_override!r} is not a supported CLI. Valid values: {valid}\"\n        )\n\n    # 3. Auto-detect installed CLI tools\n    for cli_name, model, _cmd in _CLI_BACKENDS:\n        if shutil.which(cli_name):\n            logger.info(\"No API key found — auto-detected %s CLI as LLM backend\", cli_name)\n            return model\n\n    raise RuntimeError(\n        \"No LLM API key found. headroom learn needs one of:\\n\"\n        \"  export ANTHROPIC_API_KEY=sk-ant-...   → uses claude-sonnet-4-6\\n\"\n        \"  export OPENAI_API_KEY=sk-...          → uses gpt-4o\\n\"\n        \"  export GEMINI_API_KEY=...             → uses gemini-flash-latest\\n\"\n        \"Or set HEADROOM_LEARN_CLI to a coding agent CLI (claude, gemini, codex).\\n\"\n        \"Or install one of those CLIs for auto-detection.\\n\"\n        \"Or specify a model directly: headroom learn --model <litellm-model-name>\"\n    )","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/learn/analyzer.py#L120-L156","documentation":"Raised during LLM-backend resolution in headroom learn: after no API-key env vars (ANTHROPIC_API_KEY/OPENAI_API_KEY/GEMINI_API_KEY per _MODEL_DEFAULTS) matched, the explicit HEADROOM_LEARN_CLI override was read but its value does not match any name in _CLI_BACKENDS (claude, gemini, codex and friends). ValueError with the valid list so the misconfiguration is immediately visible.","triggerScenarios":"Running `headroom learn` (or calling the backend resolver) with HEADROOM_LEARN_CLI set to a typo'd or unsupported value, e.g. HEADROOM_LEARN_CLI=claude-code, claude_cli, 'Claude', or an arbitrary binary name, while no API key env vars are set.","commonSituations":"Copying the env var from docs for a different headroom version whose backend list changed; using quotes/whitespace in shell export ('claude ' with trailing space); assuming any CLI name works because auto-detection mentioned it; case sensitivity.","solutions":["Set a valid value: export HEADROOM_LEARN_CLI=claude (or gemini / codex — exactly as listed in the error's valid values)","Check for typos, casing, and stray whitespace/quotes in the export","Alternatively drop the override and let auto-detection find an installed CLI, or export an API key (ANTHROPIC_API_KEY/OPENAI_API_KEY/GEMINI_API_KEY), or pass --model explicitly"],"exampleFix":"# before\nexport HEADROOM_LEARN_CLI=claude-code  # typo'd name\nheadroom learn\n\n# after\nexport HEADROOM_LEARN_CLI=claude\nheadroom learn","handlingStrategy":"validation","validationCode":"import os, shutil\nVALID = {'claude', 'gemini', 'codex'}  # keep in sync with the error's valid list\ncli = os.environ.get('HEADROOM_LEARN_CLI')\nif cli is not None and cli not in VALID:\n    raise SystemExit(f'HEADROOM_LEARN_CLI={cli!r} invalid; choose from {sorted(VALID)}')","typeGuard":null,"tryCatchPattern":"try:\n    headroom_learn()\nexcept ValueError as e:\n    if 'HEADROOM_LEARN_CLI' in str(e):\n        # correct the env var and retry once\n        os.environ['HEADROOM_LEARN_CLI'] = 'claude'\n        headroom_learn()\n    else:\n        raise","preventionTips":["Strip whitespace and lowercase the env var value when setting it","Validate HEADROOM_LEARN_CLI in a config-lint step before running learn","Read the error message — it lists the exact valid values for your headroom version"],"tags":["configuration","env-var","cli","validation"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}