{"record":{"id":"6112b09323f722a4","repo":"home-assistant/core","slug":"invalid-agent-selected-agent-id","errorCode":null,"errorMessage":"Invalid agent selected: {agent_id}","messagePattern":"Invalid agent selected: (.+?)","errorType":"exception","errorClass":"BackupManagerError","httpStatus":null,"severity":"error","filePath":"homeassistant/components/backup/manager.py","lineNumber":1570,"sourceCode":"                        )\n                        or \"-\"\n                    ),\n                    \"failed_folders\": \", \".join(f for f in folder_errors) or \"-\",\n                },\n            )\n\n    async def async_can_decrypt_on_download(\n        self,\n        backup_id: str,\n        *,\n        agent_id: str,\n        password: str | None,\n    ) -> None:\n        \"\"\"Check if we are able to decrypt the backup on download.\"\"\"\n        try:\n            agent = self.backup_agents[agent_id]\n        except KeyError as err:\n            raise BackupManagerError(f\"Invalid agent selected: {agent_id}\") from err\n        try:\n            backup = await agent.async_get_backup(backup_id)\n        except BackupNotFound as err:\n            raise BackupManagerError(\n                f\"Backup {backup_id} not found in agent {agent_id}\"\n            ) from err\n        # Check for None to be backwards compatible with the old BackupAgent API,\n        # this can be removed in HA Core 2025.10\n        if not backup:\n            frame.report_usage(\n                \"returns None from BackupAgent.async_get_backup\",\n                breaks_in_ha_version=\"2025.10\",\n                integration_domain=agent_id.partition(\".\")[0],\n            )\n            raise BackupManagerError(\n                f\"Backup {backup_id} not found in agent {agent_id}\"\n            )\n        reader: IO[bytes]","sourceCodeStart":1552,"sourceCodeEnd":1588,"githubUrl":"https://github.com/home-assistant/core/blob/58a3fdb3ea0538617f0a07efcfba6294de64fd59/homeassistant/components/backup/manager.py#L1552-L1588","documentation":"Raised by BackupManager.async_can_decrypt_on_download when the given agent_id is not a key in manager.backup_agents (KeyError on dict access, re-raised as BackupManagerError). It is a pure input-validation failure: the decrypt-check is asked about an agent that is not registered/loaded.","triggerScenarios":"Calling async_can_decrypt_on_download with a malformed or stale agent_id — bare domain instead of full agent_id, an agent whose config entry was removed/disabled, or an ID from a different HA instance; also races where the agent unloads between UI listing and the check.","commonSituations":"Scripts/websocket clients passing the wrong identifier; network agent integration uninstalled or entry disabled after the UI captured the ID; typos in automation payloads.","solutions":["Validate the agent_id against list(manager.backup_agents) (or the UI agent list) before calling.","Reload or re-enable the integration that provides the agent so it registers again, then retry.","Use full agent IDs including the config-entry suffix (e.g., 'backblaze_b2.abcdef123'), not the integration domain."],"exampleFix":"# before\nawait manager.async_can_decrypt_on_download(\n    backup_id, agent_id=\"backblaze\", password=pw\n)\n\n# after\nagent_id = next(a for a in manager.backup_agents if a.startswith(\"backblaze\"))\nawait manager.async_can_decrypt_on_download(\n    backup_id, agent_id=agent_id, password=pw\n)","handlingStrategy":"validation","validationCode":"if agent_id not in manager.backup_agents:\n    raise ValueError(\n        f\"unknown agent {agent_id}; known: {list(manager.backup_agents)}\"\n    )","typeGuard":"def is_registered_agent(manager, agent_id: str) -> bool:\n    return agent_id in manager.backup_agents","tryCatchPattern":"from homeassistant.components.backup.manager import BackupManagerError\n\ntry:\n    await manager.async_can_decrypt_on_download(\n        backup_id, agent_id=agent_id, password=password\n    )\nexcept BackupManagerError as err:\n    if \"Invalid agent selected\" in str(err):\n        agent_id = next(iter(manager.backup_agents), None)\n        if agent_id is None:\n            raise\n        await manager.async_can_decrypt_on_download(\n            backup_id, agent_id=agent_id, password=password\n        )\n    else:\n        raise","preventionTips":["Always validate agent_id against manager.backup_agents before calling.","Use full agent IDs with the config-entry suffix.","Re-check registration after reloading/unloading agent integrations."],"tags":["backup","agent-selection","validation","keyerror"],"backgroundTag":null,"analyzedSha":"58a3fdb3ea0538617f0a07efcfba6294de64fd59","analyzedAt":"2026-08-14T20:54:38.818Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}