← Debugging Guides

阅读中文版本

Rails ActiveRecord::PendingMigrationError — Migrations Not Run

Fix PendingMigrationError by running pending migrations, understanding db:prepare, and resolving migration conflicts before deploy.

intermediatedebuggingrubyrailsmigrations

Symptoms

  • Rails raises ActiveRecord::PendingMigrationError on any request
  • The app boots locally but errors in staging
  • A migration file was added but never applied

Possible causes

  • A new migration was committed but not run in the current environment
  • The database was reset or restored from a dump older than the migrations
  • Two branches added migrations with the same timestamp

Diagnosis steps

Show migration status

bin/rails db:migrate:status

Interpretation

The list marks pending migrations with "down", showing exactly what must run.

Apply pending migrations

bin/rails db:migrate

Interpretation

Running migrations updates schema_migrations and clears the pending state.

Root cause

Rails checks whether every migration file has a matching row in schema_migrations. If any is unapplied, it refuses requests with PendingMigrationError to avoid running against an unexpected schema.

Fix

Run bin/rails db:migrate in the affected environment, use bin/rails db:prepare in deploy scripts to create or migrate idempotently, and avoid duplicate migration timestamps by regenerating with rails g migration.

Risk note

Running db:reset or db:drop in production destroys data; use db:migrate or db:prepare only.

Verify the fix

Reload the app and confirm requests succeed; check db:migrate:status shows all migrations up.

Symptoms

The error “Rails ActiveRecord::PendingMigrationError — Migrations Not Run” points at a specific failure mode. This guide documents the symptoms you can observe, the commands that isolate the cause, the root cause, the fix, and the checks that prove the fix works.

Observed symptoms include:

  • Rails raises ActiveRecord::PendingMigrationError on any request
  • The app boots locally but errors in staging
  • A migration file was added but never applied

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Show migration status

bin/rails db:migrate:status

The list marks pending migrations with “down”, showing exactly what must run.

Step 2: Apply pending migrations

bin/rails db:migrate

Running migrations updates schema_migrations and clears the pending state.

Likely contributors, in order of frequency:

  • A new migration was committed but not run in the current environment
  • The database was reset or restored from a dump older than the migrations
  • Two branches added migrations with the same timestamp

Root Cause

Rails checks whether every migration file has a matching row in schema_migrations. If any is unapplied, it refuses requests with PendingMigrationError to avoid running against an unexpected schema.

The Fix

Run bin/rails db:migrate in the affected environment, use bin/rails db:prepare in deploy scripts to create or migrate idempotently, and avoid duplicate migration timestamps by regenerating with rails g migration.

Watch out: Running db:reset or db:drop in production destroys data; use db:migrate or db:prepare only.

# inspect and apply
bin/rails db:migrate:status
bin/rails db:migrate

# deploy hook: idempotent create-or-migrate
bin/rails db:prepare

# generate a migration with a unique timestamp
bin/rails generate migration AddStatusToOrders status:string

Verify and Prevent

Reload the app and confirm requests succeed; check db:migrate:status shows all migrations up.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.