{"record":{"id":"6eb2fa5bba48450f","repo":"home-assistant/core","slug":"api-authentication-error","errorCode":null,"errorMessage":"api_authentication_error","messagePattern":"api_authentication_error","errorType":"exception","errorClass":"ConfigEntryAuthFailed","httpStatus":null,"severity":"critical","filePath":"homeassistant/components/anthropic/coordinator.py","lineNumber":93,"sourceCode":"        )\n\n    @callback\n    @override\n    def async_set_updated_data(self, data: list[anthropic.types.ModelInfo]) -> None:\n        \"\"\"Manually update data, notify listeners and update refresh interval.\"\"\"\n        self.update_interval = UPDATE_INTERVAL_CONNECTED\n        super().async_set_updated_data(data)\n\n    async def async_update_data(self) -> list[anthropic.types.ModelInfo]:\n        \"\"\"Fetch data from the API.\"\"\"\n        try:\n            self.update_interval = UPDATE_INTERVAL_DISCONNECTED\n            result = await self.client.models.list(timeout=10.0)\n            self.update_interval = UPDATE_INTERVAL_CONNECTED\n        except anthropic.APITimeoutError as err:\n            raise TimeoutError(err.message or str(err)) from err\n        except anthropic.AuthenticationError as err:\n            raise ConfigEntryAuthFailed(\n                translation_domain=DOMAIN,\n                translation_key=\"api_authentication_error\",\n                translation_placeholders={\"message\": err.message},\n            ) from err\n        except anthropic.APIError as err:\n            raise UpdateFailed(\n                translation_domain=DOMAIN,\n                translation_key=\"api_error\",\n                translation_placeholders={\"message\": err.message},\n            ) from err\n        return result.data\n\n    def mark_connection_error(self) -> None:\n        \"\"\"Mark the connection as having an error and reschedule background check.\"\"\"\n        self.update_interval = UPDATE_INTERVAL_DISCONNECTED\n        if self.last_update_success:\n            self.last_update_success = False\n            self.async_update_listeners()","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/home-assistant/core/blob/58a3fdb3ea0538617f0a07efcfba6294de64fd59/homeassistant/components/anthropic/coordinator.py#L75-L111","documentation":"A ConfigEntryAuthFailed raised with translation key 'api_authentication_error' when the periodic client.models.list() call in the Anthropic coordinator raises anthropic.AuthenticationError. It signals the API key is no longer valid and starts Home Assistant's reauth flow for the config entry.","triggerScenarios":"await self.client.models.list(timeout=10.0) returning a 401 from the Anthropic API — revoked/rotated API key, wrong key entered in the config flow, or a key from an organization the user no longer belongs to.","commonSituations":"User regenerated the API key in the Anthropic console but did not update Home Assistant; key revoked for policy/billing reasons; typo or whitespace when pasting the key initially.","solutions":["Follow the reauth flow that Home Assistant opens and paste a currently valid Anthropic API key","Verify the key with a direct curl to https://api.anthropic.com/v1/models using x-api-key","Check the Anthropic console for revoked keys or organization membership changes"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import anthropic\n\nasync def key_valid(client: anthropic.AsyncAnthropic) -> bool:\n    try:\n        await client.models.list(timeout=10.0)\n        return True\n    except anthropic.AuthenticationError:\n        return False","typeGuard":"import anthropic\n\ndef is_auth_error(err: BaseException) -> bool:\n    return isinstance(err, anthropic.AuthenticationError)","tryCatchPattern":"try:\n    result = await self.client.models.list(timeout=10.0)\nexcept anthropic.AuthenticationError as err:\n    raise ConfigEntryAuthFailed(\n        translation_domain=DOMAIN,\n        translation_key=\"api_authentication_error\",\n        translation_placeholders={\"message\": err.message},\n    ) from err","preventionTips":["Validate the API key once at config flow time with a cheap models.list call","Store the key via Home Assistant secrets rather than pasting it repeatedly"],"tags":["home-assistant","anthropic","authentication","api-key","coordinator"],"backgroundTag":null,"analyzedSha":"58a3fdb3ea0538617f0a07efcfba6294de64fd59","analyzedAt":"2026-08-14T20:54:38.818Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}