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 # Driver

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Remove :capabilities and use only :options: Selenium::WebDriver.for(:remote, url: url, options: Selenium::WebDriver::Options.chrome).
  2. If you must use legacy capabilities temporarily, remove :options and pass only :capabilities.
  3. 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

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


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/9f61c85d8bb9b1c5. Report an issue: GitHub.