{"record":{"id":"7e0d292708a33e06","repo":"MemPalace/mempalace","slug":"anthropic-provider-requires-anthropic-api-key-env","errorCode":null,"errorMessage":"Anthropic provider requires ANTHROPIC_API_KEY env or --llm-api-key","messagePattern":"Anthropic provider requires ANTHROPIC_API_KEY env or --llm-api-key","errorType":"exception","errorClass":"LLMError","httpStatus":null,"severity":"error","filePath":"mempalace/llm_client.py","lineNumber":410,"sourceCode":"            api_key_source=source,\n        )\n\n    def check_available(self) -> tuple[bool, str]:\n        if not self.api_key:\n            return False, \"ANTHROPIC_API_KEY not set (use --llm-api-key or env)\"\n        # Don't probe — a live request would cost money. First real call will\n        # surface auth errors if the key is invalid.\n        return True, \"ok\"\n\n    def classify(\n        self,\n        system: str,\n        user: str,\n        json_mode: bool = True,\n        think: Optional[bool] = None,  # noqa: ARG002 — accepted for interface compat; Anthropic extended thinking is configured separately\n    ) -> LLMResponse:\n        if not self.api_key:\n            raise LLMError(\"Anthropic provider requires ANTHROPIC_API_KEY env or --llm-api-key\")\n        sys_prompt = system\n        if json_mode:\n            sys_prompt += \"\\n\\nRespond with valid JSON only, no prose.\"\n        body = {\n            \"model\": self.model,\n            \"max_tokens\": 2048,\n            \"temperature\": 0.1,\n            \"system\": sys_prompt,\n            \"messages\": [{\"role\": \"user\", \"content\": user}],\n        }\n        headers = {\n            \"X-API-Key\": self.api_key,\n            \"anthropic-version\": self.API_VERSION,\n        }\n        data = _http_post_json(\n            f\"{self.endpoint}/v1/messages\", body, headers=headers, timeout=self.timeout\n        )\n        try:","sourceCodeStart":392,"sourceCodeEnd":428,"githubUrl":"https://github.com/MemPalace/mempalace/blob/06cb6987f02610784fefbad4b2bd5d026d164ba6/mempalace/llm_client.py#L392-L428","documentation":"LLMError raised by AnthropicProvider.classify() when no API key is configured. The provider is constructed lazily-valid (check_available deliberately skips probing to avoid paid calls), so the missing key surfaces only at the first real classify() request via the X-API-Key header requirement.","triggerScenarios":"build_provider(\"anthropic\", model=...) without ANTHROPIC_API_KEY in the environment and without --llm-api-key; the key env var set in a different shell/session than the one running the pipeline.","commonSituations":"Enabling the external BYOK Anthropic path but forgetting the env var; running under systemd/cron where the interactive shell's exports are absent; CI lacking the secret.","solutions":["Export ANTHROPIC_API_KEY in the environment the process actually runs in","Or pass --llm-api-key / api_key= explicitly when building the provider","For local-only use, switch to the ollama provider instead — no key needed","Add a startup check: provider.api_key is truthy before the first classify"],"exampleFix":"# before\nprovider = build_provider(\"anthropic\", model=\"claude-sonnet-4-20250514\")\nprovider.classify(s, u)  # LLMError: Anthropic provider requires ANTHROPIC_API_KEY env or --llm-api-key\n\n# after\nexport ANTHROPIC_API_KEY=sk-ant-...\nprovider = build_provider(\"anthropic\", model=\"claude-sonnet-4-20250514\")\nprovider.classify(s, u)","handlingStrategy":"validation","validationCode":"import os\n\nif os.environ.get(\"MP_LLM_PROVIDER\") == \"anthropic\" and not os.environ.get(\"ANTHROPIC_API_KEY\"):\n    raise RuntimeError(\"ANTHROPIC_API_KEY not set — refusing to start BYOK path\")","typeGuard":null,"tryCatchPattern":"from mempalace.llm_client import LLMError\n\ntry:\n    provider.classify(s, u)\nexcept LLMError as e:\n    if \"ANTHROPIC_API_KEY\" in str(e):\n        raise SystemExit(\"Set ANTHROPIC_API_KEY or switch to the local ollama provider\")\n    raise","preventionTips":["Check provider.api_key is set right after construction for anthropic","Inject secrets via the environment of the actual process (systemd, CI secret store)","Default to local providers (ollama) so no key is ever required"],"tags":["llm","anthropic","api-key","configuration","byok"],"backgroundTag":null,"analyzedSha":"06cb6987f02610784fefbad4b2bd5d026d164ba6","analyzedAt":"2026-08-15T03:03:36.213Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}