SeleniumHQ/selenium · error · TypeError

expected Hash or #{Proxy.name}, got #{proxy.inspect}:#{proxy

Error message

expected Hash or #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}

What it means

Raised as a TypeError by Remote::Capabilities#proxy= when the assigned value is not a Hash, a Proxy object, or nil. The setter uses a case/when to accept Hash (converted to Proxy.new), Proxy/nil (stored directly), and rejects everything else to keep @capabilities[:proxy] always a Proxy or nil.

Source

Thrown at rb/lib/selenium/webdriver/remote/capabilities.rb:166

          elsif other.is_a? Hash
            @capabilities.merge! other
          else
            raise ArgumentError, 'argument should be a Hash or implement #capabilities'
          end
        end

        def proxy
          @capabilities[:proxy]
        end

        def proxy=(proxy)
          case proxy
          when Hash
            @capabilities[:proxy] = Proxy.new(proxy)
          when Proxy, nil
            @capabilities[:proxy] = proxy
          else
            raise TypeError, "expected Hash or #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}"
          end
        end

        def timeouts
          @capabilities[:timeouts] ||= {}
        end

        def timeouts=(timeouts)
          @capabilities[:timeouts] = timeouts
        end

        def implicit_timeout
          timeouts[:implicit]
        end

        def implicit_timeout=(timeout)
          timeouts[:implicit] = timeout
        end

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Wrap a Hash: capabilities.proxy = {http: 'http://host:8080', ssl: 'http://host:8080'}.
  2. Construct a Proxy object: capabilities.proxy = Selenium::WebDriver::Proxy.new(http: 'host:8080').
  3. If you have a raw JSON string, parse it first: capabilities.proxy = JSON.parse(json_str) (must yield a Hash).
  4. Set to nil explicitly to clear the proxy rather than assigning an empty string.

Example fix

# before
caps.proxy = ENV['HTTP_PROXY']

# after
caps.proxy = Selenium::WebDriver::Proxy.new(http: ENV['HTTP_PROXY'])
Defensive patterns

Strategy: type-guard

Validate before calling

# Validate proxy value before assignment:
unless proxy.nil? || proxy.is_a?(Hash) || proxy.is_a?(Selenium::WebDriver::Proxy)
  raise TypeError, 'proxy must be Hash, Proxy, or nil'
end
capabilities.proxy = proxy

Type guard

def valid_proxy?(obj)
  obj.nil? || obj.is_a?(Hash) || obj.is_a?(Selenium::WebDriver::Proxy)
end

Try / catch

begin
  capabilities.proxy = raw_proxy
rescue TypeError => e
  capabilities.proxy = Selenium::WebDriver::Proxy.new(http: raw_proxy.to_s)
end

Prevention

When it happens

Trigger: Assigning capabilities.proxy = 'http://host:8080' (a String). Assigning a URI object, a symbol like :direct, or an integer. Passing a custom proxy-like object that does not inherit from Proxy.

Common situations: Reading proxy config from an environment variable or YAML as a string and assigning directly. Passing a Selenium Server URL string to proxy= confusing it with the http client proxy. Version upgrades where Proxy was previously more permissive. Constructing a proxy from parsed JSON where the value is a stringified hash representation.

Related errors


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