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
- Don't roll back — write a new forward migration that reverses the column type if you truly need integers.
- 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.
- On dev machines where the data is disposable: rails db:drop db:create db:migrate to rebuild from scratch.
- 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
- Prefer reversible pairs (revert-safe up/down or change with reversible blocks) when writing type changes.
- Target specific versions with db:migrate:down VERSION= instead of stepping db:rollback.
- Treat IrreversibleMigration in down as documentation: the data transform was lossy by design.
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
- Cannot rollback: cross-item duplicates exist in snaptrade_ac
- Duplicate (coinbase_item_id, account_id) pairs exist in coin
- Duplicate (lunchflow_item_id, account_id) pairs exist in lun
- SnapTrade positions response has no results array (keys: #{r
- invalid_response
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/47b490c63f44a9fc.
Report an issue: GitHub.