home-assistant/core · warning · FileAlreadyExists

Blueprint already exists

Error message

Blueprint already exists

What it means

FileAlreadyExists is raised by _create_file when a blueprint file already exists at the target path and allow_override is False. This guards the import flow so a new import does not silently clobber a local, possibly hand-edited blueprint.

Source

Thrown at homeassistant/components/blueprint/models.py:346

        path = self.blueprint_folder / blueprint_path
        await self.hass.async_add_executor_job(path.unlink)
        self._blueprints[blueprint_path] = None

    def _create_file(
        self, blueprint: Blueprint, blueprint_path: str, allow_override: bool
    ) -> bool:
        """Create blueprint file.

        Returns true if the action overrides an existing blueprint.
        """

        path = pathlib.Path(
            self.hass.config.path(BLUEPRINT_FOLDER, self.domain, blueprint_path)
        )
        exists = path.exists()

        if not allow_override and exists:
            raise FileAlreadyExists(self.domain, blueprint_path)

        path.parent.mkdir(parents=True, exist_ok=True)
        path.write_text(blueprint.yaml(), encoding="utf-8")
        return exists

    async def async_add_blueprint(
        self, blueprint: Blueprint, blueprint_path: str, allow_override: bool = False
    ) -> bool:
        """Add a blueprint."""
        overrides_existing = await self.hass.async_add_executor_job(
            self._create_file, blueprint, blueprint_path, allow_override
        )

        self._blueprints[blueprint_path] = blueprint

        if overrides_existing:
            await self._reload_blueprint_consumers(self.hass, blueprint_path)

View on GitHub (pinned to 58a3fdb3ea)

Solutions

  1. If overwrite is intended, pass allow_override=True (in the UI, confirm the 'already exists, overwrite?' dialog)
  2. Otherwise rename the existing file first, then import to get both side by side
  3. Check for a stale copy you no longer need and delete it (after handling BlueprintInUse)

Example fix

# before
await manager.async_add_blueprint(bp, "domotics/motion.yaml")

# after
await manager.async_add_blueprint(bp, "domotics/motion.yaml", allow_override=True)
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path

def blueprint_target_free(hass, domain: str, path: str) -> bool:
    return not (Path(hass.config.path("blueprints", domain)) / path).exists()

Try / catch

from homeassistant.components.blueprint.errors import FileAlreadyExists
try:
    await manager.async_add_blueprint(bp, path)
except FileAlreadyExists:
    # ask user to confirm, then retry with allow_override=True

Prevention

When it happens

Trigger: Importing a blueprint whose computed path (often author/package/filename.yaml) already exists in config/blueprints/<domain>/ without passing allow_override=True (the UI shows a confirm-overwrite prompt that sets it).

Common situations: Re-importing an updated community blueprint; importing a different blueprint that resolves to the same filename; double-clicking import.

Related errors


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