vitessio/vitess · error
cannot run a revert migration %v: %+v
Error message
cannot run a revert migration %v: %+v
What it means
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.
Source
Thrown at go/vt/vttablet/onlineddl/executor.go:2188
completeUUID := row["migration_uuid"].ToString()
if completeUUID != revertMigration.UUID {
return 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)
}
}
}
}
return nil
}
// executeRevert is called for 'revert' migrations (SQL is of the form "revert 99caeca2_74e2_11eb_a693_f875a4d24e90", not a real SQL of course).
// In this function we:
// - figure out whether the revert is valid: can we really revert requested migration?
// - what type of migration we're reverting? (CREATE/DROP/ALTER)
// - revert appropriately to the type of migration
func (e *Executor) executeRevert(ctx context.Context, onlineDDL *schema.OnlineDDL) (err error) {
revertUUID, err := onlineDDL.GetRevertUUID(e.env.Environment().Parser())
if err != nil {
return fmt.Errorf("cannot run a revert migration %v: %+v", onlineDDL.UUID, err)
}
revertMigration, row, err := e.readMigration(ctx, revertUUID)
if err != nil {
return err
}
if err := e.validateMigrationRevertible(ctx, revertMigration, onlineDDL.UUID); err != nil {
return err
}
revertedActionStr := row["ddl_action"].ToString()
switch revertedActionStr {
case sqlparser.CreateStr:
{
// We are reverting a CREATE migration. The revert is to DROP, only we don't actually
// drop the table, we rename it into lifecycle
// Possibly this was a CREATE TABLE IF NOT EXISTS, and possibly the table already existed
// before the DDL, in which case the CREATE was a noop. In that scenario we _do not_ dropView on GitHub (pinned to 01a25a7d17)
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
Example fix
// before (hand-edited revert request) --up-sql=REVERT not-a-real-uuid // after --up-sql=REVERT 82fa7e81_2f61_11eb_b1a4_f875a4d24f90
Defensive patterns
Strategy: validation
Validate before calling
// Before submitting a revert, confirm the target UUID exists and is well-formed
migs := showVitessMigrations(t, keyspace)
target := "82fa7e81_2f61_11eb_b1a4_f875a4d24f90"
for _, m := range migs {
if m.UUID == target && m.Completed != nil {
return // safe to revert
}
}
return fmt.Errorf("revert target %s not found or not complete", target) Try / catch
err := submitRevert(ctx, targetUUID)
if err != nil && strings.Contains(err.Error(), "cannot run a revert migration") {
log.Errorf("revert %s rejected: %v", targetUUID, err)
// fall back to manual DDL or fix migration metadata
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- cannot run migration %s reverting %s: found %d artifact tabl
- migration %v cannot run because prior migration %v in same c
- direct DDL is disabled
- online DDL is disabled
- Foreign key found
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/76d50ebf730a7ed7.
Report an issue: GitHub.