home-assistant/core · error · BackupNotFound

Backup {backup_id} does not exist

Error message

Backup {backup_id} does not exist

What it means

Raised by LocalBackupAgent.get_backup_path when the requested backup_id has no entry in the _backups map (KeyError). get_backup_path is the synchronous path-lookup used by delete/restore flows, so this means the local agent has no tracked backup with that ID at all.

Source

Thrown at homeassistant/components/backup/backup.py:132

                ),
                backup.backup_id,
                backup_path,
            )
            self._backups.pop(backup_id)
            raise BackupNotFound(f"Backup {backup_id} not found")

        return backup

    @override
    def get_backup_path(self, backup_id: str) -> Path:
        """Return the local path to an existing backup.

        Raises BackupAgentError if the backup does not exist.
        """
        try:
            return self._backups[backup_id][1]
        except KeyError as err:
            raise BackupNotFound(f"Backup {backup_id} does not exist") from err

    @override
    def get_new_backup_path(self, backup: AgentBackup) -> Path:
        """Return the local path to a new backup."""
        candidate = self._backup_dir / suggested_filename(backup)
        # suggested_filename does not strip separators; refuse paths that would
        # land outside the backup directory.
        if candidate.parent != self._backup_dir:
            raise InvalidBackupFilename(
                f"Refusing to write outside {self._backup_dir}: {candidate}"
            )
        return candidate

    @override
    async def async_delete_backup(self, backup_id: str, **kwargs: Any) -> None:
        """Delete a backup file."""
        if not self._loaded_backups:
            await self._load_backups()

View on GitHub (pinned to 58a3fdb3ea)

Solutions

  1. Refresh the backup list and retry with the current backup_id from the refreshed list.
  2. Ensure you target the agent that actually holds the backup (manager.sync_agents / per-agent lookups).
  3. Catch BackupNotFound and treat 'already gone' as success for delete-style flows.
Defensive patterns

Strategy: validation

Validate before calling

tracked = local_agent._backups if False else None
# public-safe variant: list first
backups = await local_agent.async_list_backups()
if backup_id not in {b.backup_id for b in backups}:
    LOGGER.info("backup %s unknown to local agent", backup_id)

Try / catch

from homeassistant.components.backup.agent import BackupNotFound

try:
    path = local_agent.get_backup_path(backup_id)
except BackupNotFound:
    LOGGER.info("%s already gone; nothing to delete", backup_id)
    return  # idempotent delete

Prevention

When it happens

Trigger: Calling get_backup_path(backup_id) with an unknown ID — e.g., async_delete_backup on the local agent for a backup that was never loaded (the method forces _load_backups first, so the ID truly is absent), or an ID belonging to another agent.

Common situations: Deleting a backup entry from the UI after the file was already removed externally; scripts calling the websocket/API delete endpoint with a stale or foreign backup_id; race where the backup was deleted concurrently.

Related errors


AI-assisted analysis of home-assistant/core@58a3fdb3ea (2026-08-14). Data as JSON: /api/errors/f4d76d4a0f6a835b. Report an issue: GitHub.