home-assistant/core · error · InvalidBlueprint

Invalid blueprint: {msg_or_exc}

Error message

Invalid blueprint: {msg_or_exc}

What it means

InvalidBlueprint is raised from Blueprint.__init__ when the blueprint data fails the voluptuous schema (BLUEPRINT_SCHEMA or the automation/script-specific schema). The vol.Invalid is humanized via humanize_error so the message names the offending key. It is a data-shape problem in the YAML file itself, not an I/O problem.

Source

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

from .schemas import BLUEPRINT_INSTANCE_FIELDS


class Blueprint:
    """Blueprint of a configuration structure."""

    def __init__(
        self,
        data: dict[str, Any],
        *,
        path: str | None = None,
        expected_domain: str | None = None,
        schema: Callable[[Any], Any],
    ) -> None:
        """Initialize a blueprint."""
        try:
            data = self.data = schema(data)
        except vol.Invalid as err:
            raise InvalidBlueprint(expected_domain, path, data, err) from err

        # In future, we will treat this as "incorrect" and allow to recover from this
        data_domain = data[CONF_BLUEPRINT][CONF_DOMAIN]
        if expected_domain is not None and data_domain != expected_domain:
            raise InvalidBlueprint(
                expected_domain,
                path or self.name,
                data,
                (
                    f"Found incorrect blueprint type {data_domain}, expected"
                    f" {expected_domain}"
                ),
            )

        self.domain = data_domain

        missing = yaml_util.extract_inputs(data) - set(self.inputs)

View on GitHub (pinned to 58a3fdb3ea)

Solutions

  1. Read the humanized message: it names the exact key/path that failed (e.g. 'required key not provided @ data['blueprint']['name']')
  2. Open config/blueprints/<domain>/<file>.yaml and fix the reported key against the schema: blueprint.name, blueprint.domain, and a mapping under input:
  3. Validate the file as plain YAML first (python -c "import yaml,sys; yaml.safe_load(open(sys.argv[1]))") to rule out syntax errors
  4. Re-import the blueprint from its original source URL to get a known-good copy

Example fix

# before (blueprint YAML)
blueprint:
  domain: automation
  # name missing
input: {}

# after
blueprint:
  name: My blueprint
  domain: automation
input: {}
Defensive patterns

Strategy: validation

Validate before calling

import voluptuous as vol
from homeassistant.components.blueprint.models import BLUEPRINT_SCHEMA

def blueprint_valid(data: dict) -> bool:
    try:
        BLUEPRINT_SCHEMA(data)
        return True
    except vol.Invalid:
        return False

Try / catch

from homeassistant.components.blueprint.errors import InvalidBlueprint
try:
    bp = Blueprint(data, expected_domain="automation", schema=BLUEPRINT_SCHEMA)
except InvalidBlueprint as err:
    logger.warning("Rejected blueprint %s: %s", err.blueprint_name, err)

Prevention

When it happens

Trigger: Loading a blueprint YAML missing the top-level 'blueprint:' mapping, a missing 'name', missing 'domain', an 'input:' section that is not a mapping, or a value of the wrong type; triggered by async_get_blueprint, _load_blueprints at startup, or importing a URL whose YAML is malformed.

Common situations: Hand-edited blueprint file with a typo; YAML indentation error turning 'blueprint:' into a string; a script blueprint missing 'sequence'; blueprints written for an older HA schema after a breaking change.

Related errors


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