{"record":{"id":"33eba36c1dcb7132","repo":"usestrix/strix","slug":"model-connection-failed-exc","errorCode":null,"errorMessage":"Model connection failed: {exc}","messagePattern":"Model connection failed: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"strix/interface/tui/runtime.py","lineNumber":133,"sourceCode":"        candidate.max_turns = self.controller.max_turns\n        candidate.scope_mode = self.controller.scope_mode\n        candidate.diff_base = self.controller.diff_base\n        existing_targets = [\n            str(target[\"original\"])\n            for target in candidate.targets_info\n            if isinstance(target, dict) and target.get(\"original\")\n        ]\n        targets_changed = self.controller.targets != existing_targets\n        model = (load_settings().llm.model or \"\").strip()\n        # A bare prompt launches optimistically: it skips the network preflight\n        # and lets any model error surface once the agent starts, like a coding\n        # agent. A named target keeps the upfront check.\n        if verify:\n            try:\n                await preflight_model_connection(model)\n            except Exception as exc:\n                logger.exception(\"Go TUI setup model preflight failed\")\n                raise RuntimeError(f\"Model connection failed: {exc}\") from exc\n        # A confirmed target-less launch mounts the working directory for the\n        # agent to work in, without making it a scan target.\n        candidate.workspace_mount = self.controller.workspace_mount\n        if targets_changed:\n            # Rebuild the full typed set so path canonicalization and local\n            # deduplication match the CLI.\n            candidate.target = list(self.controller.targets)\n            candidate.target_list = []\n            build_targets_info(candidate)\n        prepare_run(candidate)\n        telemetry_start(candidate)\n\n        vars(self.args).update(vars(candidate))\n        self.init_run_state()\n        self.start_scan()\n\n    async def prepare_and_start(self) -> None:\n        \"\"\"Prepare a directly-launched scan once the TUI is on screen.","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/interface/tui/runtime.py#L115-L151","documentation":"Raised in runtime.py's go-path start flow when preflight_model_connection(model) raises while 'verify' is requested. The preflight (strix/interface/scan_setup.py:61) performs a minimal network call against the configured LLM before the scan begins, so misconfigured API keys, unreachable providers, or invalid model ids fail fast here instead of mid-scan. The original exception is chained and logged ('Go TUI setup model preflight failed').","triggerScenarios":"Starting a scan with a named target (verify=True) while LLM_API_KEY is missing/wrong, STRIX_LLM/llm.model names an unknown model id, the provider endpoint is unreachable, or a proxy blocks the request. The exception text of the underlying failure is embedded in the message.","commonSituations":"Expired or mistyped API key; model string not a valid LiteLLM id (e.g. 'gpt-5' vs 'openai/gpt-5'); corporate egress proxy; provider outage; .env not loaded so key is empty; region-blocked endpoint.","solutions":["Check the embedded {exc} text — it names the real cause (auth, 404 model, timeout)","Verify the key: export LLM_API_KEY correctly and confirm with a one-line curl to the provider","Confirm the model id is a valid LiteLLM identifier (provider-prefixed)","Fix network/proxy egress for the provider endpoint, then retry the start","As a last resort for prompt-only launches, note that verify is skipped for bare prompts — but named targets always preflight"],"exampleFix":"# before\nexport LLM_API_KEY=\"sk-wrong\"\nstrix -t https://example.com\n# -> Model connection failed: AuthenticationError ...\n\n# after\nexport LLM_API_KEY=\"$REAL_KEY\"\nexport STRIX_LLM=\"openai/gpt-4o\"\nstrix -t https://example.com","handlingStrategy":"try-catch","validationCode":"model = (load_settings().llm.model or \"\").strip()\nif not model or not os.environ.get(\"LLM_API_KEY\"):\n    raise SystemExit(\"set STRIX_LLM/<model> and LLM_API_KEY before starting\")","typeGuard":"def model_config_plausible() -> bool:\n    return bool((load_settings().llm.model or \"\").strip()) and bool(os.environ.get(\"LLM_API_KEY\"))","tryCatchPattern":"try:\n    await start_scan(verify=True)\nexcept RuntimeError as e:\n    if str(e).startswith(\"Model connection failed:\"):\n        diagnose_llm_config(e)  # inspect chained exc: auth vs model-id vs network\n    else:\n        raise","preventionTips":["Run a one-line provider health check before launching scans","Use provider-prefixed LiteLLM model ids","Keep keys in the environment Strix actually reads (LLM_API_KEY) and reload .env","Test with a tiny max-budget run after changing model config"],"tags":["llm","network","configuration","tui","preflight"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}