SeleniumHQ/selenium · error · ArgumentError

Can not set :service object on #{self.class}

Error message

Can not set :service object on #{self.class}

What it means

Raised by Remote::Driver#assert_arguments when a :service keyword argument is provided. Remote::Driver connects to an already-running Selenium Server or Grid endpoint, so it has no local driver service process to manage — :service is only meaningful for local driver subclasses (Chrome, Firefox, etc.) that spawn a browser driver executable.

Source

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

                       **)
          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"

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Remove the :service argument when using :remote; the remote server manages its own driver processes.
  2. Use :url (or :client_config with server_url) to point at the remote endpoint instead.
  3. If you need local driver behavior, use Selenium::WebDriver.for(:chrome, service: my_service) instead of :remote.

Example fix

# before
driver = Selenium::WebDriver.for(:remote, service: service, url: 'http://grid:4444')

# after
driver = Selenium::WebDriver.for(:remote, url: 'http://grid:4444')
Defensive patterns

Strategy: validation

Validate before calling

# Validate config before driver creation:
if driver_type == :remote && config.key?(:service)
  raise ArgumentError, ':service is not valid for :remote driver; use :url instead'
end

Type guard

def remote_compatible_config?(config)
  !config.key?(:service)
end

Try / catch

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

Prevention

When it happens

Trigger: Calling Selenium::WebDriver.for(:remote, service: my_service, url: 'http://localhost:4444'). Passing a service object intended for a local driver into a Remote driver initialization. Copying local-driver config code into a Remote driver setup.

Common situations: Switching from a local driver (:chrome with service:) to a Remote/Grid setup and forgetting to remove the :service argument. Sharing a config hash across local and remote driver creation. Misunderstanding that :service manages the driver executable, not the remote endpoint.

Related errors


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