scenic-views/scenic · error · ActiveRecord::IrreversibleMigration
#{method} is reversible only if given a revert_to_version
Error message
#{method} is reversible only if given a revert_to_version What it means
When rolling back, ActiveRecord's command recorder replays recorded statements in reverse, and Scenic's invert_drop_view, invert_update_view, and invert_replace_view all funnel into perform_scenic_inversion. That method needs the revert_to_version keyword to know which db/views definition to restore; without it there is no way to reconstruct the prior view, so it raises ActiveRecord::IrreversibleMigration ('<method> is reversible only if given a revert_to_version') instead of guessing.
Source
Thrown at lib/scenic/command_recorder.rb:50
perform_scenic_inversion(:create_view, args)
end
def invert_update_view(args)
perform_scenic_inversion(:update_view, args)
end
def invert_replace_view(args)
perform_scenic_inversion(:replace_view, args)
end
private
def perform_scenic_inversion(method, args)
scenic_args = StatementArguments.new(args)
if scenic_args.revert_to_version.nil?
message = "#{method} is reversible only if given a revert_to_version"
raise ActiveRecord::IrreversibleMigration, message
end
[method, scenic_args.invert_version.to_a]
end
end
end
View on GitHub (pinned to f2162dbddb)
Solutions
- Edit the migration to add revert_to_version naming the version that existed before the change (drop_view :searches, revert_to_version: 3; update_view :searches, version: 2, revert_to_version: 1), then re-run db:rollback - the recorder reads the migration file at rollback time, so editing after the up-run is safe
- If the rollback already aborted, fix the file and rerun the same db:rollback or db:migrate:down command; nothing ran, so no schema repair is needed
- If the change is intentionally one-way, stop rolling back past it: bring the schema forward again with db:migrate instead
Example fix
# before def change drop_view :searches end # db:rollback raises IrreversibleMigration # after def change drop_view :searches, revert_to_version: 3 end
Defensive patterns
Strategy: validation
Validate before calling
Dir[Rails.root.join('db/migrate/*.rb')].each do |file|
src = File.read(file)
next unless src =~ /(drop|update|replace)_view/
abort file + ': scenic view change lacks revert_to_version (irreversible)' unless src.include?('revert_to_version:')
end Try / catch
begin Rake::Task['db:rollback'].invoke rescue ActiveRecord::IrreversibleMigration => e puts 'rollback aborted: ' + e.message end
Prevention
- Treat revert_to_version as mandatory whenever writing drop_view, update_view, or replace_view
- Add a CI check that fails migrations containing scenic view statements without revert_to_version
- Run db:migrate:redo locally before pushing so the rollback leg is exercised
When it happens
Trigger: Running rails db:rollback, db:migrate:down VERSION=..., db:migrate:redo, or a revert block after a migration used drop_view :searches, update_view :searches, version: 2, or replace_view :searches, version: 2 without a revert_to_version keyword.
Common situations: Hand-written migrations that encode only the forward path; developers who pair revert_to_version with update_view but forget it on drop_view; CI pipelines that smoke-test with db:migrate:redo and fail on the rollback leg.
Related errors
- a transaction is required to perform a side-by-side update
- version is required
- Define view query in #{path} before migrating.
- Materialized views require Postgres 9.3 or newer
- Cannot replace materialized views
AI-assisted analysis of scenic-views/scenic@f2162dbddb (2026-08-23).
Data as JSON: /api/errors/0a8d9114bae9ed3c.
Report an issue: GitHub.