SeleniumHQ/selenium · error · ArgumentError

Cannot use both :http_client and :client_config

Error message

Cannot use both :http_client and :client_config

What it means

Raised by Remote::Driver#assert_arguments when both :http_client and :client_config keyword arguments are provided simultaneously. The driver can only derive its HTTP transport from one source: either a pre-built http_client object or a ClientConfig that the driver uses to build one internally — supplying both creates an ambiguous, conflicting configuration.

Source

Thrown at rb/lib/selenium/webdriver/remote/driver.rb:54

          assert_arguments(service, url, http_client, client_config)

          caps = process_options(options, capabilities)
          http_client ||= Remote::Http::Default.new(client_config: client_config)
          server_url = url || client_config&.server_url || "http://#{Platform.localhost}:4444/wd/hub"
          http_client.server_url = server_url
          caps['se:remoteUrl'] = server_url.to_s.chomp('/')
          super(caps: caps, http_client: http_client, **)
          @bridge.file_detector = ->((filename, *)) { File.exist?(filename) && filename.to_s }
          command_list = @bridge.command_list
          @bridge.extend(WebDriver::Remote::Features)
          @bridge.add_commands(command_list)
        end

        private

        def assert_arguments(service, url, http_client, client_config)
          raise ArgumentError, "Can not set :service object on #{self.class}" if service
          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

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Choose one HTTP configuration method: pass :client_config only, or :http_client only.
  2. If you have a ClientConfig and need custom HTTP behavior, let the driver build the client from client_config rather than also passing http_client.
  3. Audit shared config hashes to ensure only one of the two keys is present before driver creation.

Example fix

# before
driver = Selenium::WebDriver.for(:remote,
  url: url, http_client: Selenium::WebDriver::Remote::Http::Default.new,
  client_config: Selenium::WebDriver::Remote::ClientConfig.new(server_url: url))

# after
driver = Selenium::WebDriver.for(:remote,
  client_config: Selenium::WebDriver::Remote::ClientConfig.new(server_url: url, read_timeout: 120))
Defensive patterns

Strategy: validation

Validate before calling

# Ensure only one HTTP config source:
if config[:http_client] && config[:client_config]
  raise ArgumentError, 'Pass either :http_client or :client_config, not both'
end

Type guard

def single_http_config?(config)
  !(config[:http_client] && config[:client_config])
end

Try / catch

begin
  Selenium::WebDriver.for(:remote, **config)
rescue ArgumentError => e
  config.delete(:http_client) if e.message.include?('http_client')
  Selenium::WebDriver.for(:remote, **config)
end

Prevention

When it happens

Trigger: Calling Selenium::WebDriver.for(:remote, url: url, http_client: my_client, client_config: config). Reusing a shared config hash that includes client_config and also passing an explicit http_client. Migrating from http_client to client_config without removing the old argument.

Common situations: Gradual migration from the legacy :http_client API to the newer :client_config API where both end up in the call. Centralized config builders that set both defensively. Copying code snippets from different documentation versions.

Related errors


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