SeleniumHQ/selenium · error · ArgumentError
Don't use both :options and :capabilities when initializing
Error message
Don't use both :options and :capabilities when initializing #{self.class}, prefer :options What it means
Raised by Remote::Driver#process_options when both :options and :capabilities keyword arguments are provided to the driver constructor. The library wants a single source of truth for session configuration; :options (an Options object) is the modern preferred API while :capabilities (legacy) is supported separately. Passing both is ambiguous and rejected to prevent one silently overriding the other.
Source
Thrown at rb/lib/selenium/webdriver/remote/driver.rb:72
raise ArgumentError, 'Cannot use both :http_client and :client_config' if http_client && client_config
raise ArgumentError, 'Cannot use both :url and a ClientConfig#server_url' if url && client_config&.server_url
end
def devtools_url
capabilities['se:cdp']
end
def devtools_version
cdp_version = capabilities['se:cdpVersion']&.split('.')&.first
raise Error::WebDriverError, 'DevTools is not supported by the Remote Server' unless cdp_version
Integer(cdp_version)
end
def process_options(options, capabilities)
if options && capabilities
msg = "Don't use both :options and :capabilities when initializing #{self.class}, prefer :options"
raise ArgumentError, msg
elsif options.nil? && capabilities.nil?
raise ArgumentError, "#{self.class} needs :options to be set"
end
options ? options.as_json : generate_capabilities(capabilities)
end
def generate_capabilities(capabilities)
Array(capabilities).map { |cap|
if cap.is_a? Symbol
cap = WebDriver::Options.send(cap)
elsif !cap.respond_to? :as_json
msg = ":capabilities parameter only accepts objects responding to #as_json which #{cap.class} does not"
raise ArgumentError, msg
end
cap.as_json
}.inject(:merge)
end
end # DriverView on GitHub (pinned to aa36b38e69)
Solutions
- Remove :capabilities and use only :options: Selenium::WebDriver.for(:remote, url: url, options: Selenium::WebDriver::Options.chrome).
- If you must use legacy capabilities temporarily, remove :options and pass only :capabilities.
- Consolidate all capability settings into a single Options object instead of splitting across both parameters.
Example fix
# before driver = Selenium::WebDriver.for(:remote, url: url, options: Selenium::WebDriver::Options.chrome, capabilities: Selenium::WebDriver::Remote::Capabilities.chrome) # after driver = Selenium::WebDriver.for(:remote, url: url, options: Selenium::WebDriver::Options.chrome)
Defensive patterns
Strategy: validation
Validate before calling
# Ensure only one of :options or :capabilities: if config[:options] && config[:capabilities] config.delete(:capabilities) # prefer :options end Selenium::WebDriver.for(:remote, **config)
Type guard
def single_session_config?(config) !(config[:options] && config[:capabilities]) end
Try / catch
begin
Selenium::WebDriver.for(:remote, **config)
rescue ArgumentError => e
config.delete(:capabilities) if e.message.include?('options and :capabilities')
Selenium::WebDriver.for(:remote, **config)
end Prevention
- Standardize on :options for all new Selenium 4+ code.
- Remove all :capabilities usage during migration to :options.
- Audit config builders for both keys before driver creation.
When it happens
Trigger: Calling Selenium::WebDriver.for(:remote, url: url, options: opts, capabilities: caps). Migrating from capabilities to options but leaving the old capabilities argument in place. Passing a shared config hash that happens to contain both keys.
Common situations: Gradual migration from the deprecated :capabilities API to :options. Copy-pasting from mixed documentation examples. Config builders that set both 'just in case'. Using Selenium 3-era code with a Selenium 4+ gem.
Related errors
- #{self.class} needs :options to be set
- Strategy can only be one of the following: normal, eager, no
- Behavior can only be one of the following: dismiss, accept,
- Timeout keys can only be one of the following: implicit, pag
- Only Proxy objects can be passed in.
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/9f61c85d8bb9b1c5.
Report an issue: GitHub.