invoke-ai/InvokeAI · critical · MigrationError

Database contains unknown legacy migration version

Error message

Database contains unknown legacy migration version: {legacy_version}

What it means

When bootstrapping the modern applied_migrations table from the legacy migration-version scheme, each legacy version is mapped to migration id 'migration_{version}'. If that id is not registered in the current MigrationSet, the code rolls back and raises MigrationError, refusing to guess about the DB state.

Solutions

  1. Run the InvokeAI version that registers the missing migration_{version} first, then upgrade stepwise
  2. Restore a DB backup consistent with the running version
  3. Rebuild a fresh database and re-import models if the old DB is not needed

Example fix

# before: brand-new build against ancient db
invokeai-web --root /data/invokeai  # MigrationError: unknown legacy version 5
# after: install the intermediate version that registers migration_5, run it, then upgrade
pip install invokeai==<version-with-migration_5> && invokeai-web --root /data/invokeai
Defensive patterns

Strategy: try-catch

Validate before calling

import sqlite3
cursor = sqlite3.connect(db_path).cursor()
legacy = [r[0] for r in cursor.execute("SELECT version FROM model_manager_migrations")]
registered = {m.id for m in migration_set.migrations}
missing = [v for v in legacy if f"migration_{v}" not in registered]
assert not missing, f"legacy versions not in this build: {missing}"

Try / catch

try:
    services.run_migrations()
except MigrationError as e:
    if "unknown legacy migration version" in str(e):
        logger.critical("Legacy DB newer than this build: %s", e)
        raise
    raise

Prevention

When it happens

Trigger: Upgrading from an old InvokeAI install whose database records legacy version numbers, where the running build has no migration registered with id migration_{legacy_version} (downgrade or divergent build).

Common situations: First launch of a modern InvokeAI against a very old database; downgraded install encountering a legacy DB; custom/forked migration sets that renamed migration IDs.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/2230490ccc2a9ac3. Report an issue: GitHub.

Appendix: source

Thrown at invokeai/app/services/shared/sqlite_migrator/sqlite_migrator_impl.py:175

                """
            )
        except sqlite3.Error as e:
            msg = f"Problem creating applied_migrations table: {e}"
            self._logger.error(msg)
            cursor.connection.rollback()
            raise MigrationError(msg) from e

    def _bootstrap_applied_migrations_from_legacy_versions(self, cursor: sqlite3.Cursor) -> None:
        """Backfills applied migration IDs from legacy numeric migration rows."""
        try:
            cursor.execute("SELECT version FROM migrations WHERE version > 0 ORDER BY version;")
            legacy_versions = [row[0] for row in cursor.fetchall()]
            registered_migration_ids = self._migration_set.migrations_by_id
            for legacy_version in legacy_versions:
                migration_id = f"migration_{legacy_version}"
                if migration_id not in registered_migration_ids:
                    cursor.connection.rollback()
                    raise MigrationError(f"Database contains unknown legacy migration version: {legacy_version}")
                cursor.execute(
                    "SELECT legacy_version FROM applied_migrations WHERE migration_id = ?;",
                    (migration_id,),
                )
                migration_row = cursor.fetchone()
                if migration_row is not None and migration_row[0] != legacy_version:
                    cursor.connection.rollback()
                    raise MigrationError(
                        "Database contains inconsistent applied migration state: "
                        f"{migration_id} is recorded with legacy version {migration_row[0]}, "
                        f"expected {legacy_version}"
                    )
                cursor.execute(
                    "SELECT migration_id FROM applied_migrations WHERE legacy_version = ?;",
                    (legacy_version,),
                )
                legacy_row = cursor.fetchone()
                if legacy_row is not None and legacy_row[0] != migration_id:

View on GitHub (pinned to 0b6a024f2f)