SeleniumHQ/selenium · error · ArgumentError

Cannot use both :client_config and :open_timeout/:read_timeo

Error message

Cannot use both :client_config and :open_timeout/:read_timeout

What it means

Raised by Http::Default#initialize when both :client_config and :open_timeout or :read_timeout keyword arguments are provided. The Default client builds its HTTP configuration from a single ClientConfig object; passing standalone timeouts alongside a client_config creates ambiguity about which timeout value wins, so the constructor rejects the combination outright.

Source

Thrown at rb/lib/selenium/webdriver/remote/http/default.rb:35

# specific language governing permissions and limitations
# under the License.
require 'ipaddr'

module Selenium
  module WebDriver
    module Remote
      module Http
        # @api private
        class Default < Common
          # Initializes object.
          # Warning: Setting {#open_timeout} to non-nil values will cause a separate thread to spawn.
          # Debuggers that freeze the process will not be able to evaluate any operations if that happens.
          # @param [ClientConfig] client_config - Configuration used to build the HTTP client.
          # @param [Numeric] open_timeout - Open timeout to apply to HTTP client.
          # @param [Numeric] read_timeout - Read timeout (seconds) to apply to HTTP client.
          def initialize(client_config: nil, open_timeout: nil, read_timeout: nil)
            if client_config && (open_timeout || read_timeout)
              raise ArgumentError, 'Cannot use both :client_config and :open_timeout/:read_timeout'
            end

            client_config ||= ClientConfig.new
            client_config.open_timeout = open_timeout if open_timeout
            client_config.read_timeout = read_timeout if read_timeout
            super(client_config: client_config)
          end

          def open_timeout
            client_config.open_timeout
          end

          def read_timeout
            client_config.read_timeout
          end

          def open_timeout=(value)
            client_config.open_timeout = value

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Set timeouts on the ClientConfig object only: ClientConfig.new(open_timeout: 30, read_timeout: 60).
  2. Or use the legacy standalone timeouts without client_config: Default.new(open_timeout: 30).
  3. When building client_config dynamically, merge timeout values into it rather than passing them separately.

Example fix

# before
client = Selenium::WebDriver::Remote::Http::Default.new(
  client_config: config, open_timeout: 30)

# after
config.open_timeout = 30
client = Selenium::WebDriver::Remote::Http::Default.new(client_config: config)
Defensive patterns

Strategy: validation

Validate before calling

# Ensure only one timeout config source:
if config[:client_config] && (config[:open_timeout] || config[:read_timeout])
  raise ArgumentError, 'Use either :client_config or :open_timeout/:read_timeout, not both'
end

Type guard

def single_timeout_config?(config)
  !(config[:client_config] && (config[:open_timeout] || config[:read_timeout]))
end

Try / catch

begin
  Selenium::WebDriver::Remote::Http::Default.new(**config)
rescue ArgumentError => e
  raise unless e.message.include?('client_config')
  config[:client_config].open_timeout = config.delete(:open_timeout)
  config[:client_config].read_timeout = config.delete(:read_timeout)
  Selenium::WebDriver::Remote::Http::Default.new(**config)
end

Prevention

When it happens

Trigger: Calling Selenium::WebDriver::Remote::Http::Default.new(client_config: config, open_timeout: 30). Passing read_timeout from a shared config hash while also providing a client_config. Migrating to client_config but leaving old timeout kwargs in the call.

Common situations: Migration from the legacy open_timeout/read_timeout constructor args to the client_config API. Config builders that set timeouts on the client_config AND pass them as kwargs. Copy-pasting from different gem versions' documentation.

Understand the failure class

Related errors


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