rails/rails · warning · ActionDispatch::TestHelpers::PageDumpHelper::InvalidResponse
Response is a redirection!
Error message
Response is a redirection!
What it means
Raised as ActionDispatch::TestHelpers::PageDumpHelper::InvalidResponse from save_page (the private engine behind save_and_open_page) when response.redirection? is true. The helper writes response.body to an HTML file to open in a browser, but a 3xx redirect has an empty/Location-only body unsuitable for inspection, so it refuses rather than write a misleading dump.
Source
Thrown at actionpack/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb:16
# frozen_string_literal: true
module ActionDispatch
module TestHelpers
module PageDumpHelper
class InvalidResponse < StandardError; end
# Saves the content of response body to a file and tries to open it in your browser.
# Launchy must be present in your Gemfile for the page to open automatically.
def save_and_open_page(path = html_dump_default_path)
save_page(path).tap { |s_path| open_file(s_path) }
end
private
def save_page(path = html_dump_default_path)
raise InvalidResponse.new("Response is a redirection!") if response.redirection?
path = Pathname.new(path)
path.dirname.mkpath
File.write(path, response.body)
path
end
def open_file(path)
require "launchy"
Launchy.open(path)
rescue LoadError
warn "File saved to #{path}.\nPlease install the launchy gem to open the file automatically."
end
def html_dump_default_path
Rails.root.join("tmp/html_dump", "#{method_name}_#{DateTime.current.to_i}.html").to_s
end
end
endView on GitHub (pinned to 2c224ba8f2)
Solutions
- Call follow_redirect! before save_and_open_page to land on the final rendered page.
- If you intended a render, fix the controller (remove the redirect_to, or assert the redirect is wrong).
- To inspect the redirect itself, assert response.status / response.location instead of dumping the body.
- For multi-step flows, use the integration session's follow_redirect! repeatedly until response.redirection? is false.
Example fix
# before
post posts_path, params: { post: attrs }
save_and_open_page # raises: response is a 302
# after
post posts_path, params: { post: attrs }
follow_redirect!
save_and_open_page # now dumps the rendered show page Defensive patterns
Strategy: validation
Validate before calling
# In tests, follow redirects before dumping. def dump_after_follow follow_redirect! while response.redirection? save_and_open_page end
Type guard
# @return [Boolean] response is dumpable (not a redirect) def dumpable_response? response&.response_code && !response.redirection? end
Try / catch
# Not really rescuable in a useful way; just guard: save_and_open_page unless response.redirection?
Prevention
- Always follow_redirect! before save_and_open_page.
- If a redirect is unexpected, assert response.status first to pin the cause.
- Use save_and_open_page only on rendered (2xx) responses.
- Prefer assert_select / assert_response over visual dumps in CI.
When it happens
Trigger: In a request/integration test, calling save_and_open_page (or save_page) right after an action that issued redirect_to — e.g. a successful create action that redirects to show. The test asserts follow_redirect! was not called, so the response is still the 302.
Common situations: Debugging a controller test where you expected a render but got a redirect; calling save_and_open_page inside a block before follow_redirect!; integration test that hits a before_action redirecting for auth.
Related errors
- Cannot redirect to nil!
- Unsafe redirect to #{location.to_s.truncate(100).inspect}, p
- Path relative URL redirect detected: #{url.inspect}
- The action '#{action}' could not be found for #{self.class.n
- The #{missing_action} action could not be found for the #{fi
AI-assisted analysis of rails/rails@2c224ba8f2 (2026-08-10).
Data as JSON: /api/errors/df2b8f6de091b861.
Report an issue: GitHub.