HKUDS/DeepTutor · error · LLMAuthenticationError

Anthropic API key is missing from the active LLM profile.

Error message

Anthropic API key is missing from the active LLM profile.

What it means

_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.

Source

Thrown at deeptutor/services/llm/cloud_provider.py:664

                except json.JSONDecodeError:
                    continue
        finally:
            await resp_cm.__aexit__(None, None, None)


async def _anthropic_complete(
    model: str,
    prompt: str,
    system_prompt: str,
    api_key: str | None,
    base_url: str | None,
    messages: list[dict[str, object]] | None = None,
    max_tokens: int | None = None,
    temperature: float | None = None,
) -> str:
    """Anthropic (Claude) API completion."""
    if not api_key:
        raise LLMAuthenticationError(
            "Anthropic API key is missing from the active LLM profile.",
            provider="anthropic",
        )

    # Build URL using unified utility
    effective_base = base_url or "https://api.anthropic.com/v1"
    url = build_chat_url(effective_base, binding="anthropic")

    # Build headers using unified utility
    headers = build_auth_headers(api_key, binding="anthropic")

    # Build messages - handle pre-built messages array
    if messages:
        # Filter out system messages for Anthropic (system is a separate parameter)
        msg_list = [m for m in messages if m.get("role") != "system"]
        system_content = next(
            (m["content"] for m in messages if m.get("role") == "system"),
            system_prompt,

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Add the Anthropic API key to the active profile / environment (ANTHROPIC_API_KEY) and retry.
  2. Verify with a print of whether the resolved api_key is empty before calling.
  3. If the key lives in a secret manager, confirm it was fetched into the runtime settings.
  4. As a stopgap, switch to a provider whose key is configured.

Example fix

// before
resp = await complete(prompt=p, binding="anthropic", model="claude-sonnet-4", api_key=key)

# after
if not (key or "").strip():
    raise RuntimeError("ANTHROPIC_API_KEY is not set")
resp = await complete(prompt=p, binding="anthropic", model="claude-sonnet-4", api_key=key)
Defensive patterns

Strategy: validation

Validate before calling

api_key = (os.getenv("ANTHROPIC_API_KEY") or "").strip()
if not api_key:
    raise RuntimeError("ANTHROPIC_API_KEY is required for the anthropic binding")
resp = await complete(prompt=p, binding="anthropic", model=m, api_key=api_key)

Type guard

def has_anthropic_key(api_key: str | None) -> bool:
    return isinstance(api_key, str) and bool(api_key.strip())

Try / catch

try:
    resp = await complete(prompt=p, binding="anthropic", model=m, api_key=k)
except LLMAuthenticationError as e:
    if e.provider == "anthropic":
        prompt_user_for_key("anthropic")
    raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/a9fa4b36daec593b. Report an issue: GitHub.