{"record":{"id":"bc4d2b29704def7e","repo":"invoke-ai/InvokeAI","slug":"database-contains-inconsistent-applied-migration-s-bc4d2b","errorCode":null,"errorMessage":"Database contains inconsistent applied migration state: {migration_id} is applied, but legacy version {legacy_version} is missing","messagePattern":"Database contains inconsistent applied migration state: (.+?) is applied, but legacy version (.+?) is missing","errorType":"exception","errorClass":"MigrationError","httpStatus":null,"severity":"error","filePath":"invokeai/app/services/shared/sqlite_migrator/sqlite_migrator_impl.py","lineNumber":259,"sourceCode":"        applied_rows = cursor.fetchall()\n\n        cursor.execute(\"SELECT version FROM migrations WHERE version > 0;\")\n        legacy_versions = {row[0] for row in cursor.fetchall()}\n\n        for row in applied_rows:\n            migration_id = row[0]\n            legacy_version = row[1]\n            migration = registered_migrations[migration_id]\n            if migration.to_version is None:\n                continue\n            if legacy_version != migration.to_version:\n                raise MigrationError(\n                    \"Database contains inconsistent applied migration state: \"\n                    f\"{migration_id} is recorded with legacy version {legacy_version}, \"\n                    f\"expected {migration.to_version}\"\n                )\n            if legacy_version not in legacy_versions:\n                raise MigrationError(\n                    \"Database contains inconsistent applied migration state: \"\n                    f\"{migration_id} is applied, but legacy version {legacy_version} is missing\"\n                )\n\n    def _needs_applied_migrations_bootstrap(self, cursor: sqlite3.Cursor) -> bool:\n        \"\"\"Checks whether legacy numeric rows need to be written to applied_migrations.\"\"\"\n        cursor.execute(\"SELECT version FROM migrations WHERE version > 0;\")\n        legacy_versions = {row[0] for row in cursor.fetchall()}\n        if len(legacy_versions) == 0:\n            return False\n\n        cursor.execute(\"SELECT name FROM sqlite_master WHERE type='table' AND name='applied_migrations';\")\n        if cursor.fetchone() is None:\n            return True\n\n        cursor.execute(\"SELECT legacy_version FROM applied_migrations WHERE legacy_version IS NOT NULL;\")\n        applied_legacy_versions = {row[0] for row in cursor.fetchall()}\n        return not legacy_versions.issubset(applied_legacy_versions)","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/services/shared/sqlite_migrator/sqlite_migrator_impl.py#L241-L277","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Restore the database from a consistent backup.","Re-insert the missing legacy version row in the migrations table if you can verify the schema change was actually applied.","Remove the orphaned row from applied_migrations if the migration truly was never applied, then let run_migrations apply it cleanly."],"exampleFix":"// before: applied_migrations says version 4 applied, migrations table lacks it\n// after: remove the orphaned applied record so the migrator can re-apply\nDELETE FROM applied_migrations WHERE migration_id = 'migration_4';","handlingStrategy":"validation","validationCode":"import sqlite3\nconn = sqlite3.connect(db_path)\napplied = {r[0] for r in conn.execute(\"SELECT legacy_version FROM applied_migrations WHERE legacy_version IS NOT NULL\")}\nlegacy = {r[0] for r in conn.execute(\"SELECT version FROM migrations WHERE version > 0\")}\norphaned = applied - legacy\nif orphaned:\n    print(\"applied_migrations rows missing legacy versions:\", sorted(orphaned))","typeGuard":null,"tryCatchPattern":"try:\n    migrator.run_migrations()\nexcept MigrationError as e:\n    if \"legacy version\" in str(e) and \"missing\" in str(e):\n        raise SystemExit(f\"Migration history inconsistent; restore backup: {e}\")\n    raise","preventionTips":["Treat migrations/applied_migrations as an atomic pair; never delete from one only.","Back up the DB before interrupting or debugging migrations.","Restore full-file DB backups, not selective table restores."],"tags":["database","sqlite","migration","data-corruption"],"backgroundTag":"migration-state-inconsistent","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}