SeleniumHQ/selenium · error · ArgumentError

Can't set the server URL for #{self.class}; the service prov

Error message

Can't set the server URL for #{self.class}; the service provides it

What it means

Local drivers (Chrome, Firefox, Edge, etc.) launch their own driver service process and derive the server URL from that service; the URL cannot be supplied by the caller. assert_local_arguments raises ArgumentError if a :url is provided or if a client_config with a server_url is set. To connect to an already-running remote endpoint, use the :remote driver instead.

Source

Thrown at rb/lib/selenium/webdriver/common/local_driver.rb:63

        default_options = Options.send(browser)
        options ||= default_options

        unless options.is_a?(default_options.class)
          raise ArgumentError, ":options must be an instance of #{default_options.class}"
        end

        finder = WebDriver::DriverFinder.new(options, service)
        options.binary = finder.browser_path if options.respond_to?(:binary) && finder.browser_path?
        service.executable_path = finder.driver_path
        options.browser_version = nil if options.respond_to?(:binary) && options.binary
        options.as_json
      end

      private

      def assert_local_arguments(url, http_client, client_config)
        if url || client_config&.server_url
          raise ArgumentError, "Can't set the server URL for #{self.class}; the service provides it"
        elsif http_client && client_config
          raise ArgumentError, 'Cannot use both :http_client and :client_config'
        end
      end
    end
  end
end

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Remove the :url argument when using a local driver; Selenium starts and addresses the service for you.
  2. To connect to a pre-existing driver service, use Selenium::WebDriver.for(:remote, url: 'http://host:port', options: opts).
  3. If using client_config, do not set server_url on it for a local driver.

Example fix

# before
driver = Selenium::WebDriver.for(:chrome, url: 'http://localhost:9515')

# after (local)
driver = Selenium::WebDriver.for(:chrome)
# or (remote to existing service)
driver = Selenium::WebDriver.for(:remote, url: 'http://localhost:9515', options: Selenium::WebDriver::Chrome::Options.new)
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, 'do not pass :url to a local driver' if url && local_browser?

Try / catch

begin
  Selenium::WebDriver.for(:chrome)
rescue ArgumentError => e
  raise unless e.message.include?('server URL')
  Selenium::WebDriver.for(:remote, url: url, options: opts)
end

Prevention

When it happens

Trigger: Passing url: 'http://localhost:9515' to Selenium::WebDriver.for(:chrome, url: ...). Constructing a ClientConfig with server_url and passing it to a local browser driver. Reusing a remote-driver initialization block for a local driver.

Common situations: Migrating code from a remote setup and forgetting to remove the explicit URL. Wanting to attach to a manually-started driver service instead of letting Selenium manage it.

Related errors


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