Introduction

ActiveRecord::PendingMigrationError blocks Rails application startup when the database schema version does not match the migrations in your codebase. This is a safety mechanism to prevent running code against an incompatible database schema, but it can cause outages if not handled properly during deployment.

Symptoms

  • ActiveRecord::PendingMigrationError: Migrations are pending. To resolve this issue, run: bin/rails db:migrate
  • Application refuses to start after code deploy
  • Error appears on first request after deployment
  • Development database works but production fails
  • Multiple developers have conflicting migration timestamps

Example error: ``` ActiveRecord::PendingMigrationError: Migrations are pending. To resolve this issue, run: bin/rails db:migrate RAILS_ENV=production

Existing migrations: 20260401120000 AddStatusToUsers 20260405143000 CreateOrders 20260408090000 AddIndexToOrdersUserId

Database schema version: 20260401120000 ```

Common Causes

  • Deployment code includes new migrations but database was not migrated
  • Migration was run on one replica but not all database servers
  • Migration file was committed but not run before deploying
  • Schema file out of sync between developers
  • Migration was reverted locally but not in production

Step-by-Step Fix

  1. 1.Check current migration status:
  2. 2.```bash
  3. 3.bin/rails db:migrate:status

# Output: # up 20260401120000 Add status to users # up 20260405143000 Create orders # down 20260408090000 Add index to orders user id ```

  1. 1.Run pending migrations:
  2. 2.```bash
  3. 3.# Development
  4. 4.bin/rails db:migrate

# Production (with output) bin/rails db:migrate RAILS_ENV=production --trace

# On Heroku heroku run rails db:migrate ```

  1. 1.Handle migration conflicts (two devs created migrations at same time):
  2. 2.```bash
  3. 3.# Check for conflicting timestamps
  4. 4.ls db/migrate/ | sort

# If timestamps collide, rename one migration file: mv db/migrate/20260408090000_add_index.rb db/migrate/20260408090001_add_index.rb ```

  1. 1.Fix a failed migration:
  2. 2.```bash
  3. 3.# Rollback the failed migration
  4. 4.bin/rails db:rollback STEP=1

# Fix the migration file, then re-run bin/rails db:migrate ```

  1. 1.Force schema load if migrations are problematic:
  2. 2.```bash
  3. 3.# WARNING: This will drop and recreate the database from schema.rb
  4. 4.bin/rails db:drop db:create db:schema:load

# Only use in development or when you have backups ```

Prevention

  • Run bin/rails db:migrate as part of your CI pipeline against a test database
  • Add a deployment step that runs migrations before restarting the application
  • Use bin/rails db:migrate:status in CI to catch pending migrations early
  • Configure Capistrano/Fly.io/Heroku to run migrations automatically during deploy
  • Never commit a migration and deploy the code in separate PRs
  • Use reversible blocks in migrations for safe rollback:
ruby
class AddStatusToUsers < ActiveRecord::Migration[7.1]
  def change
    add_column :users, :status, :integer, default: 0, null: false
  end
end