{"record":{"id":"2cd79d74e02fae4b","repo":"ory/hydra","slug":"migration-down-unable-count-existing-migration","errorCode":null,"errorMessage":"migration down: unable count existing migration","messagePattern":"migration down: unable count existing migration","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"oryx/popx/migrator.go","lineNumber":345,"sourceCode":"\n// Down runs pending \"down\" migrations and rolls back the\n// database by the specified number of steps.\n// If step <= 0, all down migrations are run.\nfunc (mb *MigrationBox) Down(ctx context.Context, steps int) (err error) {\n\tctx, span := startSpan(ctx, MigrationDownOpName, trace.WithAttributes(attribute.Int(\"steps\", steps)))\n\tdefer otelx.End(span, &err)\n\n\tif steps <= 0 {\n\t\tsteps = math.MaxInt\n\t}\n\tremainingSteps := steps\n\n\tc := mb.c.WithContext(ctx)\n\treturn errors.WithStack(mb.exec(ctx, func() (err error) {\n\t\tmtn := sanitizedMigrationTableName(c)\n\t\tcount, err := c.Count(mtn)\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"migration down: unable count existing migration\")\n\t\t}\n\t\tattemptSteps := min(remainingSteps, count)\n\n\t\tmfs := mb.migrationsDown.sortAndFilter(mb.c.Dialect.Name(), mb.migrationFallbacks()...)\n\t\tslices.Reverse(mfs)\n\t\tif len(mfs) > count {\n\t\t\t// skip all migrations that were not yet applied\n\t\t\tmfs = mfs[len(mfs)-count:]\n\t\t}\n\n\t\treverted := 0\n\t\tdefer func() {\n\t\t\tmigrationsToRevertCount := min(attemptSteps, len(mfs))\n\t\t\tmb.l.Debugf(\"Successfully reverted %d/%d migrations.\", reverted, migrationsToRevertCount)\n\t\t\tif err != nil {\n\t\t\t\tmb.l.WithError(err).Error(\"Problem reverting migrations.\")\n\t\t\t}\n\t\t}()","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/popx/migrator.go#L327-L363","documentation":"Before running Down migrations, the migrator counts rows in the schema_migration table to determine how many steps can be reverted. This error wraps a failure of that COUNT query against the migrations table. It means the tracking table could not be read at all.","triggerScenarios":"Calling MigrationBox.Down when the schema_migration table does not exist (migrations never initialized), is corrupted, or the query fails due to permissions/connection issues.","commonSituations":"Running Down on a fresh database that never had migrations applied; wrong DSN pointing to an empty database; table renamed manually; revoked SELECT privileges.","solutions":["Confirm you are connected to the correct database (check DSN)","Verify the schema_migration table exists; run migrations init/up first if the database was never migrated","Check the wrapped cause for the underlying SQL error and address privileges or connectivity"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"var n int\nif err := db.QueryRow(\"SELECT COUNT(*) FROM schema_migration\").Scan(&n); err != nil {\n    return fmt.Errorf(\"schema_migration table not readable; run migrations init/up first: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := box.Down(ctx, 1); err != nil {\n    if strings.Contains(err.Error(), \"unable count existing migration\") {\n        // verify DSN and that the DB has been migrated before attempting rollback\n    }\n    return err\n}","preventionTips":["Never run Down on a database that has not been migrated","Verify DSN/environment before destructive operations","Keep SELECT privileges on the tracking table for the migration user"],"tags":["database","migration","go"],"backgroundTag":"migration-table-missing","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"}