SeleniumHQ/selenium · error · ArgumentError
:options must be an instance of #{default_options.class}
Error message
:options must be an instance of #{default_options.class} What it means
When starting a local driver, process_options validates that the supplied :options object is an instance of the Options subclass that matches the target browser (e.g. Chrome::Options for Chrome, Firefox::Options for Firefox). If the options object's class does not match, ArgumentError is raised. This prevents silently sending the wrong capability payload to the driver service.
Source
Thrown at rb/lib/selenium/webdriver/common/local_driver.rb:49
begin
yield(caps, http_client) if block_given?
rescue Selenium::WebDriver::Error::WebDriverError
@service_manager&.stop
raise
end
end
def service_url(service)
@service_manager = service.launch
@service_manager.uri
end
def process_options(options, service)
default_options = Options.send(browser)
options ||= default_options
unless options.is_a?(default_options.class)
raise ArgumentError, ":options must be an instance of #{default_options.class}"
end
finder = WebDriver::DriverFinder.new(options, service)
options.binary = finder.browser_path if options.respond_to?(:binary) && finder.browser_path?
service.executable_path = finder.driver_path
options.browser_version = nil if options.respond_to?(:binary) && options.binary
options.as_json
end
private
def assert_local_arguments(url, http_client, client_config)
if url || client_config&.server_url
raise ArgumentError, "Can't set the server URL for #{self.class}; the service provides it"
elsif http_client && client_config
raise ArgumentError, 'Cannot use both :http_client and :client_config'
end
endView on GitHub (pinned to aa36b38e69)
Solutions
- Construct the Options class that matches the browser: Selenium::WebDriver::Chrome::Options.new for :chrome.
- If you do not need custom options, omit the :options argument so Selenium uses the default Options.send(browser) instance.
- Double-check that the symbol passed to Driver.for matches the Options subclass you instantiated.
Example fix
# before options = Selenium::WebDriver::Firefox::Options.new driver = Selenium::WebDriver.for(:chrome, options: options) # after options = Selenium::WebDriver::Chrome::Options.new driver = Selenium::WebDriver.for(:chrome, options: options)
Defensive patterns
Strategy: type-guard
Validate before calling
expected = Selenium::WebDriver::Options.send(browser).class
raise ArgumentError, "options must be #{expected}" unless options.is_a?(expected) Type guard
def options_match_browser?(options, browser) options.is_a?(Selenium::WebDriver::Options.send(browser).class) end
Try / catch
begin
Selenium::WebDriver.for(browser, options: options)
rescue ArgumentError => e
raise unless e.message.include?('must be an instance of')
options = Selenium::WebDriver::Options.send(browser)
Selenium::WebDriver.for(browser, options: options)
end Prevention
- Keep the :browser symbol and the Options subclass in sync in a single config object.
- Derive the Options class from the browser symbol: Selenium::WebDriver::Options.send(browser).
- Omit :options when you only need defaults.
When it happens
Trigger: Passing Selenium::WebDriver::Firefox::Options.new as :options to Selenium::WebDriver.for(:chrome, options:). Passing a plain Hash or a remote Capabilities object instead of an Options instance. Mixing Edge::Options with a Chrome driver.
Common situations: Copy-pasting an Options setup block from another browser and changing only the :browser symbol. Switching the browser without updating the Options class. Passing an Options object whose class is a parent or unrelated type.
Related errors
- Can't set the server URL for #{self.class}; the service prov
- could not find extension at #{path.inspect}
- Cannot use both :http_client and :client_config
- These options are not w3c compliant: #{options}
- expected String or Symbol, got #{key.inspect}:#{key.class}
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/76f2cf4283748969.
Report an issue: GitHub.