SeleniumHQ/selenium · error · ArgumentError
#{self.class} needs :options to be set
Error message
#{self.class} needs :options to be set What it means
Raised by Remote::Driver#process_options when neither :options nor :capabilities is provided to the driver constructor. Remote::Driver requires at least one to know what browser session to request from the server — without it, the W3C new-session request would have no 'capabilities' field and every server would reject it.
Source
Thrown at rb/lib/selenium/webdriver/remote/driver.rb:74
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 # Driver
end # Remote
end # WebDriverView on GitHub (pinned to aa36b38e69)
Solutions
- Provide an Options object: Selenium::WebDriver.for(:remote, url: url, options: Selenium::WebDriver::Options.chrome).
- If using a dynamic browser name, build options conditionally but ensure the result is never nil: options = Selenium::WebDriver::Options.send(browser_name.to_sym).
- Validate your config hash has a non-nil :options value before passing it to the driver constructor.
Example fix
# before driver = Selenium::WebDriver.for(:remote, url: url) # after driver = Selenium::WebDriver.for(:remote, url: url, options: Selenium::WebDriver::Options.chrome)
Defensive patterns
Strategy: validation
Validate before calling
# Ensure options is non-nil: raise ArgumentError, ':options is required for :remote' unless config[:options] || config[:capabilities] # or set a default: config[:options] ||= Selenium::WebDriver::Options.chrome Selenium::WebDriver.for(:remote, **config)
Type guard
def has_session_config?(config) !config[:options].nil? || !config[:capabilities].nil? end
Try / catch
begin
Selenium::WebDriver.for(:remote, **config)
rescue ArgumentError => e
raise unless e.message.include?('needs :options')
Selenium::WebDriver.for(:remote, options: Selenium::WebDriver::Options.chrome, **config)
end Prevention
- Always pass an explicit Options object to :remote driver creation.
- Guard conditional options construction to never return nil.
- Validate config hashes have a non-nil :options before driver creation.
When it happens
Trigger: Calling Selenium::WebDriver.for(:remote, url: url) with no options or capabilities. Passing an empty hash or only :url/:http_client. A config builder that conditionally sets options but the condition evaluates to nil.
Common situations: Forgetting to specify browser options when switching from a local driver (which infers them from the driver type) to :remote. Nil-valued config keys being silently dropped by double-splat. Refactoring that moved options construction behind a conditional branch that wasn't taken.
Related errors
- Don't use both :options and :capabilities when initializing
- Invalid arguments: #{opts.keys}
- Can not set :service object on #{self.class}
- Cannot use both :http_client and :client_config
- Select element doesn't contain any option element
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/c29c0eadb9ebace1.
Report an issue: GitHub.