invoke-ai/InvokeAI · error · MigrationError

Database contains inconsistent applied migration state: {mig

Error message

Database contains inconsistent applied migration state: {migration_id} is applied, but legacy version {legacy_version} is missing

What it means

The applied_migrations table says a legacy migration is applied, but the corresponding numeric version row is missing from the legacy migrations table. The two tables must mirror each other; this asymmetry means migration history is incomplete, so startup aborts.

Source

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

        applied_rows = cursor.fetchall()

        cursor.execute("SELECT version FROM migrations WHERE version > 0;")
        legacy_versions = {row[0] for row in cursor.fetchall()}

        for row in applied_rows:
            migration_id = row[0]
            legacy_version = row[1]
            migration = registered_migrations[migration_id]
            if migration.to_version is None:
                continue
            if legacy_version != migration.to_version:
                raise MigrationError(
                    "Database contains inconsistent applied migration state: "
                    f"{migration_id} is recorded with legacy version {legacy_version}, "
                    f"expected {migration.to_version}"
                )
            if legacy_version not in legacy_versions:
                raise MigrationError(
                    "Database contains inconsistent applied migration state: "
                    f"{migration_id} is applied, but legacy version {legacy_version} is missing"
                )

    def _needs_applied_migrations_bootstrap(self, cursor: sqlite3.Cursor) -> bool:
        """Checks whether legacy numeric rows need to be written to applied_migrations."""
        cursor.execute("SELECT version FROM migrations WHERE version > 0;")
        legacy_versions = {row[0] for row in cursor.fetchall()}
        if len(legacy_versions) == 0:
            return False

        cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='applied_migrations';")
        if cursor.fetchone() is None:
            return True

        cursor.execute("SELECT legacy_version FROM applied_migrations WHERE legacy_version IS NOT NULL;")
        applied_legacy_versions = {row[0] for row in cursor.fetchall()}
        return not legacy_versions.issubset(applied_legacy_versions)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Restore the database from a consistent backup.
  2. Re-insert the missing legacy version row in the migrations table if you can verify the schema change was actually applied.
  3. Remove the orphaned row from applied_migrations if the migration truly was never applied, then let run_migrations apply it cleanly.

Example fix

// before: applied_migrations says version 4 applied, migrations table lacks it
// after: remove the orphaned applied record so the migrator can re-apply
DELETE FROM applied_migrations WHERE migration_id = 'migration_4';
Defensive patterns

Strategy: validation

Validate before calling

import sqlite3
conn = sqlite3.connect(db_path)
applied = {r[0] for r in conn.execute("SELECT legacy_version FROM applied_migrations WHERE legacy_version IS NOT NULL")}
legacy = {r[0] for r in conn.execute("SELECT version FROM migrations WHERE version > 0")}
orphaned = applied - legacy
if orphaned:
    print("applied_migrations rows missing legacy versions:", sorted(orphaned))

Try / catch

try:
    migrator.run_migrations()
except MigrationError as e:
    if "legacy version" in str(e) and "missing" in str(e):
        raise SystemExit(f"Migration history inconsistent; restore backup: {e}")
    raise

Prevention

When it happens

Trigger: run_migrations() -> _validate_existing_applied_legacy_migrations: an applied row's legacy_version is not found among versions fetched from the legacy migrations table (legacy_versions set).

Common situations: Someone deleted rows from the legacy migrations table while keeping applied_migrations; a failed bootstrap or interrupted migration left one table updated and the other not; copying database tables selectively.

Related errors


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