{"record":{"id":"a9fa4b36daec593b","repo":"HKUDS/DeepTutor","slug":"anthropic-api-key-is-missing-from-the-active-llm-p","errorCode":null,"errorMessage":"Anthropic API key is missing from the active LLM profile.","messagePattern":"Anthropic API key is missing from the active LLM profile\\.","errorType":"error_code","errorClass":"LLMAuthenticationError","httpStatus":null,"severity":"error","filePath":"deeptutor/services/llm/cloud_provider.py","lineNumber":664,"sourceCode":"                except json.JSONDecodeError:\n                    continue\n        finally:\n            await resp_cm.__aexit__(None, None, None)\n\n\nasync def _anthropic_complete(\n    model: str,\n    prompt: str,\n    system_prompt: str,\n    api_key: str | None,\n    base_url: str | None,\n    messages: list[dict[str, object]] | None = None,\n    max_tokens: int | None = None,\n    temperature: float | None = None,\n) -> str:\n    \"\"\"Anthropic (Claude) API completion.\"\"\"\n    if not api_key:\n        raise LLMAuthenticationError(\n            \"Anthropic API key is missing from the active LLM profile.\",\n            provider=\"anthropic\",\n        )\n\n    # Build URL using unified utility\n    effective_base = base_url or \"https://api.anthropic.com/v1\"\n    url = build_chat_url(effective_base, binding=\"anthropic\")\n\n    # Build headers using unified utility\n    headers = build_auth_headers(api_key, binding=\"anthropic\")\n\n    # Build messages - handle pre-built messages array\n    if messages:\n        # Filter out system messages for Anthropic (system is a separate parameter)\n        msg_list = [m for m in messages if m.get(\"role\") != \"system\"]\n        system_content = next(\n            (m[\"content\"] for m in messages if m.get(\"role\") == \"system\"),\n            system_prompt,","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/services/llm/cloud_provider.py#L646-L682","documentation":"_anthropic_complete guards on the api_key argument before building the request: Anthropic's Messages API always requires an x-api-key header, so a falsy key cannot be defaulted or placeholder-substituted. LLMAuthenticationError is raised with provider='anthropic' and no network call is attempted.","triggerScenarios":"Calling complete(binding='anthropic'|'claude', ...) when the resolved profile has no Anthropic key; key env var unset or set to empty string; settings JSON selected an Anthropic provider but the secret was never stored.","commonSituations":"User switched provider to Claude without adding the key; ANTHROPIC_API_KEY unset in the shell launching the server; secret redacted in CI; profile shared without its key.","solutions":["Add the Anthropic API key to the active profile / environment (ANTHROPIC_API_KEY) and retry.","Verify with a print of whether the resolved api_key is empty before calling.","If the key lives in a secret manager, confirm it was fetched into the runtime settings.","As a stopgap, switch to a provider whose key is configured."],"exampleFix":"// before\nresp = await complete(prompt=p, binding=\"anthropic\", model=\"claude-sonnet-4\", api_key=key)\n\n# after\nif not (key or \"\").strip():\n    raise RuntimeError(\"ANTHROPIC_API_KEY is not set\")\nresp = await complete(prompt=p, binding=\"anthropic\", model=\"claude-sonnet-4\", api_key=key)","handlingStrategy":"validation","validationCode":"api_key = (os.getenv(\"ANTHROPIC_API_KEY\") or \"\").strip()\nif not api_key:\n    raise RuntimeError(\"ANTHROPIC_API_KEY is required for the anthropic binding\")\nresp = await complete(prompt=p, binding=\"anthropic\", model=m, api_key=api_key)","typeGuard":"def has_anthropic_key(api_key: str | None) -> bool:\n    return isinstance(api_key, str) and bool(api_key.strip())","tryCatchPattern":"try:\n    resp = await complete(prompt=p, binding=\"anthropic\", model=m, api_key=k)\nexcept LLMAuthenticationError as e:\n    if e.provider == \"anthropic\":\n        prompt_user_for_key(\"anthropic\")\n    raise","preventionTips":["Check required provider keys during app bootstrap.","Never commit profiles containing empty key fields; validate schema.","Route all anthropic calls through one factory that injects the validated key."],"tags":["llm","anthropic","authentication","api-key","configuration"],"backgroundTag":"missing-api-key","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}