teamcapybara/capybara · critical · ArgumentError
rack-test requires a rack application, but none was given
Error message
rack-test requires a rack application, but none was given
What it means
Capybara::RackTest::Driver must be constructed with a Rack application; it drives your app in-process through Rack::Test and has no other target. The initializer raises ArgumentError when app is falsy. In practice this means Capybara.app (or the app block passed to a registered driver) is nil when the driver is instantiated on the first visit/current_session call.
Source
Thrown at lib/capybara/rack_test/driver.rb:17
# frozen_string_literal: true
require 'rack/test'
require 'rack/utils'
require 'mini_mime'
require 'nokogiri'
class Capybara::RackTest::Driver < Capybara::Driver::Base
DEFAULT_OPTIONS = {
respect_data_method: false,
follow_redirects: true,
redirect_limit: 5
}.freeze
attr_reader :app, :options
def initialize(app, **options)
raise ArgumentError, 'rack-test requires a rack application, but none was given' unless app
super()
@app = app
@options = DEFAULT_OPTIONS.merge(options)
end
def browser
@browser ||= Capybara::RackTest::Browser.new(self)
end
def follow_redirects?
@options[:follow_redirects]
end
def redirect_limit
@options[:redirect_limit]
end
View on GitHub (pinned to 15b5fdb76e)
Solutions
- Set the app before use: Capybara.app = MySinatraApp (or MyRailsApp, or a Rack builder) so the driver receives it.
- In Rails, make sure specs load the environment (rails_helper) so Capybara.app picks up Rails.application automatically.
- In custom driver registrations, pass the block argument through: Capybara.register_driver(:rack_test) { |app| Capybara::RackTest::Driver.new(app, **opts) }.
- If you meant to hit an external site, switch to selenium/cuprite and set Capybara.app_host - rack_test cannot do this.
Example fix
# before Capybara.default_driver = :rack_test visit '/widgets' # Capybara.app is nil # after Capybara.app = MySinatraApp Capybara.default_driver = :rack_test visit '/widgets'
Defensive patterns
Strategy: validation
Validate before calling
raise 'Capybara.app must be set before using rack_test' if Capybara.app.nil? Capybara.default_driver = :rack_test
Type guard
def rack_app_configured? !Capybara.app.nil? end
Prevention
- Assign Capybara.app in a single bootstrap file loaded by every entry point (rails_helper, spec_helper, rake tasks).
- Never drop the |app| block argument in Capybara.register_driver.
- Remember rack_test only drives an in-process Rack app - external URLs need a browser driver plus app_host.
When it happens
Trigger: Capybara.default_driver = :rack_test with Capybara.app never set, then visit '/'; a custom registration dropping the block arg (Capybara.register_driver :my_driver { |_| Capybara::RackTest::Driver.new(nil) }); helper code like Capybara::RackTest::Driver.new(params[:app]) receiving nil.
Common situations: Standalone scripts or RSpec specs that skip rails_helper and never assign Capybara.app; testing a Sinatra/Rack app but assuming Capybara autodiscovers it; attempting to point rack_test at an external URL (unsupported - it needs the Rack object, not a host).
Related errors
- redirected more than #{driver.redirect_limit} times, check f
- This driver doesn't support case insensitive attribute match
- The rack_test driver does not process CSS
- Value cannot be an Array when 'multiple' attribute is not pr
- Cannot unselect option from single select box.
AI-assisted analysis of teamcapybara/capybara@15b5fdb76e (2026-08-21).
Data as JSON: /api/errors/cfb7360d0aad606f.
Report an issue: GitHub.