{"record":{"id":"fd0a9d6703ea7421","repo":"home-assistant/core","slug":"error-communicating-with-airpatrol-api-err","errorCode":null,"errorMessage":"Error communicating with AirPatrol API: {err}","messagePattern":"Error communicating with AirPatrol API: (.+?)","errorType":"exception","errorClass":"UpdateFailed","httpStatus":null,"severity":"error","filePath":"homeassistant/components/airpatrol/coordinator.py","lineNumber":62,"sourceCode":"\n    @override\n    async def _async_update_data(self) -> dict[str, dict[str, Any]]:\n        \"\"\"Update unit data from AirPatrol API.\"\"\"\n        return {unit_data[\"unit_id\"]: unit_data for unit_data in await self._get_data()}\n\n    async def _get_data(self, retry: bool = False) -> list[dict[str, Any]]:\n        \"\"\"Fetch data from API.\"\"\"\n        try:\n            return await self.api.get_data()\n        except AirPatrolAuthenticationError as auth_err:\n            if retry:\n                raise ConfigEntryAuthFailed(\n                    \"Authentication with AirPatrol failed\"\n                ) from auth_err\n            await self._update_token()\n            return await self._get_data(retry=True)\n        except AirPatrolError as err:\n            raise UpdateFailed(\n                f\"Error communicating with AirPatrol API: {err}\"\n            ) from err\n\n    async def _update_token(self) -> None:\n        \"\"\"Refresh the AirPatrol API client and update the access token.\"\"\"\n        session = async_get_clientsession(self.hass)\n        try:\n            self.api = await AirPatrolAPI.authenticate(\n                session,\n                self.config_entry.data[CONF_EMAIL],\n                self.config_entry.data[CONF_PASSWORD],\n            )\n        except AirPatrolAuthenticationError as auth_err:\n            raise ConfigEntryAuthFailed(\n                \"Authentication with AirPatrol failed\"\n            ) from auth_err\n\n        self.hass.config_entries.async_update_entry(","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/home-assistant/core/blob/58a3fdb3ea0538617f0a07efcfba6294de64fd59/homeassistant/components/airpatrol/coordinator.py#L44-L80","documentation":"UpdateFailed raised when get_data() raises an AirPatrolError that is not an authentication error — the generic API communication failure path during coordinator updates. Entities go unavailable and the coordinator retries on its schedule.","triggerScenarios":"api.get_data() raises AirPatrolError: HTTP 5xx from the cloud, network timeouts, malformed JSON, or rate limiting after the single auth-retry logic declines to retry non-auth errors.","commonSituations":"AirPatrol cloud instability, too-frequent polling hitting rate limits, transient internet outages, or breaking API changes after a provider-side update.","solutions":["Check whether the AirPatrol app/cloud is also failing (service-side incident).","Verify Home Assistant internet connectivity.","Reduce polling frequency if rate limiting is suspected (adjust SCAN_INTERVAL).","Wait for coordinator retry — transient API errors self-heal.","Update the airpatrol library if the API contract changed."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"def is_airpatrol_api_error(err: Exception) -> bool:\n    return isinstance(err, UpdateFailed) and str(err).startswith(\"Error communicating with AirPatrol API\")","tryCatchPattern":"try:\n    data = await coordinator.async_data()\nexcept UpdateFailed as err:\n    if not isinstance(err.__cause__, AirPatrolAuthenticationError):\n        # transient API failure: back off and let the coordinator retry\n        await asyncio.sleep(coordinator.update_interval.total_seconds())","preventionTips":["Keep the polling interval at or above the vendor's comfortable rate to avoid throttling.","Do not fan out multiple coordinator refreshes in parallel automations.","Distinguish auth (ConfigEntryAuthFailed) from generic failures before choosing a fix."],"tags":["home-assistant","airpatrol","cloud-api","transient"],"backgroundTag":null,"analyzedSha":"58a3fdb3ea0538617f0a07efcfba6294de64fd59","analyzedAt":"2026-08-14T20:54:38.818Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}