invoke-ai/InvokeAI · critical · MigrationError

Database is at version {version}, expected {expected}

Error message

Database is at version {version}, expected {expected}

What it means

_run_migration wraps each migration in a transaction and verifies the database's current user_version matches the migration's declared from_version before executing. If the DB is at a different version, the migration's assumptions are violated and a MigrationError is raised, aborting (and rolling back) the migration.

Source

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

        if self._db._db_path is not None:
            timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
            self._backup_path = self._db._db_path.parent / f"{self._db._db_path.stem}_backup_{timestamp}.db"
            self._logger.info(f"Backing up database to {str(self._backup_path)}")
            with closing(sqlite3.connect(self._backup_path)) as backup_conn:
                self._db._conn.backup(backup_conn)
        else:
            self._logger.info("Using in-memory database, no backup needed")

    def _run_migration(self, migration: Migration) -> None:
        """Runs a single migration."""
        try:
            # Using sqlite3.Connection as a context manager commits a the transaction on exit, or rolls it back if an
            # exception is raised.
            with self._db._conn as conn:
                cursor = conn.cursor()
                self._create_applied_migrations_table(cursor)
                if migration.from_version is not None and self._get_current_version(cursor) != migration.from_version:
                    raise MigrationError(
                        f"Database is at version {self._get_current_version(cursor)}, expected {migration.from_version}"
                    )
                self._logger.debug(f"Running migration '{migration.id}'")

                # Run the actual migration
                migration.callback(cursor)

                if migration.to_version is not None:
                    cursor.execute("INSERT INTO migrations (version) VALUES (?);", (migration.to_version,))
                cursor.execute(
                    "INSERT INTO applied_migrations (migration_id, legacy_version) VALUES (?, ?);",
                    (migration.id, migration.to_version),
                )

                self._logger.debug(f"Successfully ran migration '{migration.id}'")
        # We want to catch *any* error, mirroring the behaviour of the sqlite3 module.
        except Exception as e:
            # The connection context manager has already rolled back the migration, so we don't need to do anything.

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Bring the InvokeAI install to the version matching the DB's migration state
  2. Restore a DB backup whose version matches the expected from_version
  3. Check PRAGMA user_version on the DB and confirm which build should run it
  4. Back up the DB before retrying migrations

Example fix

# inspect version
sqlite3 /data/invokeai/invokeai.db 'PRAGMA user_version;'
# before: running mismatched build
# after: upgrade so app version == db version
pip install -U invokeai && invokeai-web --root /data/invokeai
Defensive patterns

Strategy: try-catch

Validate before calling

import sqlite3
cursor = sqlite3.connect(db_path).cursor()
version = cursor.execute("PRAGMA user_version").fetchone()[0]
assert version == expected_from_version, f"db at {version}, migration expects {expected_from_version}"

Try / catch

try:
    services.run_migrations()
except MigrationError as e:
    if "expected" in str(e) and "Database is at version" in str(e):
        logger.critical("Version mismatch between app and DB: %s", e)
        raise
    raise

Prevention

When it happens

Trigger: run_migrations applying a migration whose from_version is set but the sqlite PRAGMA user_version differs — e.g. DB already partially migrated, migrated by a different version, or starting from a non-zero DB created elsewhere.

Common situations: Running an older InvokeAI binary against a DB migrated by a newer one; restoring an old DB snapshot mid-migration; copying a DB between installs with divergent histories.

Related errors


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