{"record":{"id":"76d50ebf730a7ed7","repo":"vitessio/vitess","slug":"cannot-run-a-revert-migration-v-v","errorCode":null,"errorMessage":"cannot run a revert migration %v: %+v","messagePattern":"cannot run a revert migration (.+?): %\\+v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/onlineddl/executor.go","lineNumber":2188,"sourceCode":"\t\t\t\tcompleteUUID := row[\"migration_uuid\"].ToString()\n\t\t\t\tif completeUUID != revertMigration.UUID {\n\t\t\t\t\treturn fmt.Errorf(\"can not revert migration %s on table %s because it is not the last migration to complete on that table. The last migration to complete was %s\", revertMigration.UUID, revertMigration.Table, completeUUID)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// executeRevert is called for 'revert' migrations (SQL is of the form \"revert 99caeca2_74e2_11eb_a693_f875a4d24e90\", not a real SQL of course).\n// In this function we:\n// - figure out whether the revert is valid: can we really revert requested migration?\n// - what type of migration we're reverting? (CREATE/DROP/ALTER)\n// - revert appropriately to the type of migration\nfunc (e *Executor) executeRevert(ctx context.Context, onlineDDL *schema.OnlineDDL) (err error) {\n\trevertUUID, err := onlineDDL.GetRevertUUID(e.env.Environment().Parser())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot run a revert migration %v: %+v\", onlineDDL.UUID, err)\n\t}\n\n\trevertMigration, row, err := e.readMigration(ctx, revertUUID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := e.validateMigrationRevertible(ctx, revertMigration, onlineDDL.UUID); err != nil {\n\t\treturn err\n\t}\n\n\trevertedActionStr := row[\"ddl_action\"].ToString()\n\tswitch revertedActionStr {\n\tcase sqlparser.CreateStr:\n\t\t{\n\t\t\t// We are reverting a CREATE migration. The revert is to DROP, only we don't actually\n\t\t\t// drop the table, we rename it into lifecycle\n\t\t\t// Possibly this was a CREATE TABLE IF NOT EXISTS, and possibly the table already existed\n\t\t\t// before the DDL, in which case the CREATE was a noop. In that scenario we _do not_ drop","sourceCodeStart":2170,"sourceCodeEnd":2206,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/onlineddl/executor.go#L2170-L2206","documentation":"This error is returned by executeRevert when it cannot extract the UUID of the migration being reverted from the revert migration's 'schema' or request payload. Online DDL reverts work by parsing the original migration UUID out of the REVERT statement; if that parsing fails (GetRevertUUID returns an error), the revert cannot proceed. The wrapped underlying error is preserved with %+v formatting.","triggerScenarios":"Running `ALTER VITESS_MIGRATION ... REVERT <uuid>` (or vtctldclient ApplySchema with revert) where the revert payload's original UUID cannot be parsed — e.g. a malformed revert request whose online DDL comment/metadata does not contain a valid UUID.","commonSituations":"Hand-crafted or edited migration requests in _vt.schema_migrations, corruption of the migration metadata, or calling the revert API on a migration row whose revert target string was truncated or was never created by vttablet's normal online DDL flow.","solutions":["Inspect the migration row in _vt.schema_migrations (SHOW VITESS_MIGRATIONS) and verify the revert target string contains a valid UUID","Re-issue the revert using the exact UUID shown by SHOW VITESS_MIGRATIONS rather than a hand-edited value","Check the wrapped error in the log message (%+v) for the root cause from GetRevertUUID","If the migration metadata is corrupt, re-run the original migration instead of reverting"],"exampleFix":"// before (hand-edited revert request)\n--up-sql=REVERT not-a-real-uuid\n// after\n--up-sql=REVERT 82fa7e81_2f61_11eb_b1a4_f875a4d24f90","handlingStrategy":"validation","validationCode":"// Before submitting a revert, confirm the target UUID exists and is well-formed\nmigs := showVitessMigrations(t, keyspace)\ntarget := \"82fa7e81_2f61_11eb_b1a4_f875a4d24f90\"\nfor _, m := range migs {\n    if m.UUID == target && m.Completed != nil {\n        return // safe to revert\n    }\n}\nreturn fmt.Errorf(\"revert target %s not found or not complete\", target)","typeGuard":null,"tryCatchPattern":"err := submitRevert(ctx, targetUUID)\nif err != nil && strings.Contains(err.Error(), \"cannot run a revert migration\") {\n    log.Errorf(\"revert %s rejected: %v\", targetUUID, err)\n    // fall back to manual DDL or fix migration metadata\n}","preventionTips":["Only issue REVERT statements using UUIDs copied exactly from SHOW VITESS_MIGRATIONS","Never hand-edit rows in _vt.schema_migrations","Only revert migrations that reached status 'complete'","Test revert flows in staging before production"],"tags":["online-ddl","migration","revert"],"backgroundTag":"invalid-migration-revert","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}