we-promise/sure · error · ActiveRecord::IrreversibleMigration

postal_code was changed from integer to string; alphanumeric

Error message

postal_code was changed from integer to string; alphanumeric values cannot be cast back to integer

What it means

Raised as ActiveRecord::IrreversibleMigration by the down method of ChangePostalCodeToStringInAddresses (db/migrate/20260428120000_change_postal_code_to_string_in_addresses.rb:7). The up direction permanently converts addresses.postal_code from integer to string (using postal_code::text). Once any row has stored an alphanumeric postal code (e.g. Canadian 'K1A 0B1' or UK 'SW1A 1AA'), casting back to integer would fail or corrupt data, so the rollback is explicitly forbidden rather than attempted.

Source

Thrown at db/migrate/20260428120000_change_postal_code_to_string_in_addresses.rb:7

class ChangePostalCodeToStringInAddresses < ActiveRecord::Migration[7.2]
  def up
    change_column :addresses, :postal_code, :string, using: "postal_code::text"
  end

  def down
    raise ActiveRecord::IrreversibleMigration, "postal_code was changed from integer to string; alphanumeric values cannot be cast back to integer"
  end
end

View on GitHub (pinned to e69894adb9)

Solutions

  1. Don't roll back — write a new forward migration that reverses the column type if you truly need integers.
  2. If you only meant to re-run a different migration, target it explicitly with db:migrate:down VERSION=<that one> instead of db:rollback stepping.
  3. On dev machines where the data is disposable: rails db:drop db:create db:migrate to rebuild from scratch.
  4. If integer postal codes are genuinely required, first check no row matches /[^0-9]/ in postal_code, then add a new change_column migration.
Defensive patterns

Strategy: fallback

Validate before calling

abort 'postal_code rollback is forbidden' if ActiveRecord::Base.connection.migration_context.get_all_versions.include?(20260428120000.to_s)

Try / catch

begin
  rails_rollback
rescue ActiveRecord::IrreversibleMigration
  # expected for int->string data migrations; write a new forward migration instead
end

Prevention

When it happens

Trigger: Running rails db:rollback, db:migrate:down VERSION=20260428120000, or any tooling that rewinds past this migration after it has run — regardless of whether alphanumeric values actually exist; the down unconditionally raises.

Common situations: Developers habitually rolling back to re-run a neighboring migration and stepping one step too far; schema.rb vs migration version drift; attempting db:rollback on production while debugging.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/47b490c63f44a9fc. Report an issue: GitHub.