{"record":{"id":"d56f91f85708464c","repo":"ory/hydra","slug":"neither-normal-s-nor-legacy-migration-s-exis","errorCode":null,"errorMessage":"neither normal (%s) nor legacy migration (%s) exist","messagePattern":"neither normal \\((.+?)\\) nor legacy migration \\((.+?)\\) exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"oryx/popx/migrator.go","lineNumber":383,"sourceCode":"\t\t\tif i >= attemptSteps {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tl := mb.l.WithField(\"version\", mi.Version).WithField(\"migration_name\", mi.Name).WithField(\"migration_file\", mi.Path)\n\t\t\tl.Debugf(\"handling migration %s\", mi.Name)\n\t\t\texists, err := c.Where(\"version = ?\", mi.Version).Exists(mtn)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"problem checking for migration version %s\", mi.Version)\n\t\t\t}\n\n\t\t\tif !exists && len(mi.Version) > 14 {\n\t\t\t\tlegacyVersion := mi.Version[:14]\n\t\t\t\tlegacyVersionExists, err := c.Where(\"version = ?\", legacyVersion).Exists(mtn)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn errors.Wrapf(err, \"problem checking for legacy migration version %s\", legacyVersion)\n\t\t\t\t}\n\n\t\t\t\tif !legacyVersionExists {\n\t\t\t\t\treturn errors.Errorf(\"neither normal (%s) nor legacy migration (%s) exist\", mi.Version, legacyVersion)\n\t\t\t\t}\n\t\t\t} else if !exists {\n\t\t\t\treturn errors.Errorf(\"migration version %s does not exist\", mi.Version)\n\t\t\t}\n\n\t\t\tif err := mi.Valid(); err != nil {\n\t\t\t\treturn errors.WithStack(err)\n\t\t\t}\n\n\t\t\tif mb.shouldNotUseTransaction(mi) {\n\t\t\t\terr := mi.Runner(mi, c)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn errors.WithStack(err)\n\t\t\t\t}\n\n\t\t\t\t// #nosec G201 - mtn is a system-wide const\n\t\t\t\tif err := c.RawQuery(fmt.Sprintf(\"DELETE FROM %s WHERE version = ?\", mtn), mi.Version).Exec(); err != nil {\n\t\t\t\t\treturn errors.Wrapf(err, \"problem deleting migration version %s. YOUR DATABASE MAY BE IN AN INCONSISTENT STATE! MANUAL INTERVENTION REQUIRED!\", mi.Version)","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/popx/migrator.go#L365-L401","documentation":"During Down, if neither the migration's full-length version nor its legacy 14-char truncated version exists in schema_migration, the migrator cannot map the rollback to an applied migration and aborts. This prevents rolling back a migration that the tracking table says was never applied.","triggerScenarios":"Calling Down when the migration count says rows exist but the specific candidate migration's version (and its legacy form) is missing from schema_migration — e.g. rows were manually deleted, or migrations were applied by a different tool/version that recorded different versions.","commonSituations":"Manual cleanup of schema_migration rows; running Down against a database migrated by another tool (goose, golang-migrate) with a different versioning scheme; truncated vs full timestamp mismatch after DB restore from partial backup.","solutions":["Inspect schema_migration rows and compare with your migration files' versions","If the migration was truly applied, manually INSERT the missing version row (full-length format) and re-run Down","If it was never applied, verify you are on the right database/DSN and skip this migration","Restore consistency from a backup if rows were deleted accidentally"],"exampleFix":"// before: row missing, Down aborts\n// after: restore the tracked version then re-run Down\n// INSERT INTO schema_migration (version) VALUES ('20221012101010');","handlingStrategy":"validation","validationCode":"// verify every down-candidate version is tracked before calling Down\nfor _, v := range expectedVersions {\n    var ok bool\n    err := db.QueryRow(\"SELECT EXISTS(SELECT 1 FROM schema_migration WHERE version=? OR version=?)\", v, v[:min(14,len(v))]).Scan(&ok)\n    if err != nil || !ok { return fmt.Errorf(\"version %s not tracked\", v) }\n}","typeGuard":null,"tryCatchPattern":"if err := box.Down(ctx, 1); err != nil {\n    if strings.Contains(err.Error(), \"neither normal nor legacy migration exist\") {\n        // compare schema_migration rows with migration files, restore missing rows or correct DSN\n    }\n    return err\n}","preventionTips":["Never hand-delete rows from schema_migration","Use one migration tool consistently per database","Back up schema_migration before restores or bulk edits","Verify DSN points to the intended database"],"tags":["database","migration","go"],"backgroundTag":"migration-version-not-found","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}