pallets/flask · error · ValueError

Cannot register a blueprint on itself

Error message

Cannot register a blueprint on itself

What it means

A ValueError from `Blueprint.register_blueprint` (src/flask/sansio/blueprints.py:269-270), guarding the nested-blueprints feature (Flask 2.0). Registering a blueprint as a child of itself (`bp is self`) would create an infinite parent/child cycle when `register()` later walks `_blueprints` to mount children, so Flask rejects the identity case immediately. Note it only catches direct self-registration — the check is `blueprint is self`.

Source

Thrown at src/flask/sansio/blueprints.py:270

        """
        return BlueprintSetupState(self, app, options, first_registration)

    @setupmethod
    def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None:
        """Register a :class:`~flask.Blueprint` on this blueprint. Keyword
        arguments passed to this method will override the defaults set
        on the blueprint.

        .. versionchanged:: 2.0.1
            The ``name`` option can be used to change the (pre-dotted)
            name the blueprint is registered with. This allows the same
            blueprint to be registered multiple times with unique names
            for ``url_for``.

        .. versionadded:: 2.0
        """
        if blueprint is self:
            raise ValueError("Cannot register a blueprint on itself")
        self._blueprints.append((blueprint, options))

    def register(self, app: App, options: dict[str, t.Any]) -> None:
        """Called by :meth:`Flask.register_blueprint` to register all
        views and callbacks registered on the blueprint with the
        application. Creates a :class:`.BlueprintSetupState` and calls
        each :meth:`record` callback with it.

        :param app: The application this blueprint is being registered
            with.
        :param options: Keyword arguments forwarded from
            :meth:`~Flask.register_blueprint`.

        .. versionchanged:: 2.3
            Nested blueprints now correctly apply subdomains.

        .. versionchanged:: 2.1
            Registering the same blueprint with the same name multiple

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. Fix the receiver/argument mix-up: call `parent.register_blueprint(child)` with two distinct Blueprint objects, or `app.register_blueprint(bp)` to mount on the application.
  2. If iterating a collection of blueprints to nest under a parent, exclude the parent from the collection.

Example fix

# before
api = Blueprint("api", __name__)
api.register_blueprint(api)

# after
api = Blueprint("api", __name__)
v1 = Blueprint("v1", __name__)
api.register_blueprint(v1, url_prefix="/v1")
Defensive patterns

Strategy: validation

Validate before calling

if child is parent:
    raise ValueError('cannot nest blueprint on itself')
parent.register_blueprint(child)

Type guard

def can_nest(parent, child):
    return parent is not child

Prevention

When it happens

Trigger: `bp.register_blueprint(bp)` — passing the exact same Blueprint object to its own `register_blueprint`. Usually a typo where the parent was meant: `child.register_blueprint(child)` instead of `parent.register_blueprint(child)`.

Common situations: Copy-paste errors while wiring nested blueprint hierarchies; loops that programmatically mount a list of blueprints onto a parent where the parent itself is accidentally in the list; confusing `app.register_blueprint(bp)` with `bp.register_blueprint(...)`.

Related errors


AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31). Data as JSON: /data/errors/5ce18a7d043f8c7a.json. Report an issue: GitHub ↗.