{"record":{"id":"1f333b7730f23249","repo":"SeleniumHQ/selenium","slug":"expected-hash-or-proxy-name-got-proxy-inspec","errorCode":null,"errorMessage":"expected Hash or #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}","messagePattern":"expected Hash or #(.+?), got #(.+?):#(.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"rb/lib/selenium/webdriver/remote/capabilities.rb","lineNumber":166,"sourceCode":"          elsif other.is_a? Hash\n            @capabilities.merge! other\n          else\n            raise ArgumentError, 'argument should be a Hash or implement #capabilities'\n          end\n        end\n\n        def proxy\n          @capabilities[:proxy]\n        end\n\n        def proxy=(proxy)\n          case proxy\n          when Hash\n            @capabilities[:proxy] = Proxy.new(proxy)\n          when Proxy, nil\n            @capabilities[:proxy] = proxy\n          else\n            raise TypeError, \"expected Hash or #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}\"\n          end\n        end\n\n        def timeouts\n          @capabilities[:timeouts] ||= {}\n        end\n\n        def timeouts=(timeouts)\n          @capabilities[:timeouts] = timeouts\n        end\n\n        def implicit_timeout\n          timeouts[:implicit]\n        end\n\n        def implicit_timeout=(timeout)\n          timeouts[:implicit] = timeout\n        end","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/remote/capabilities.rb#L148-L184","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Wrap a Hash: capabilities.proxy = {http: 'http://host:8080', ssl: 'http://host:8080'}.","Construct a Proxy object: capabilities.proxy = Selenium::WebDriver::Proxy.new(http: 'host:8080').","If you have a raw JSON string, parse it first: capabilities.proxy = JSON.parse(json_str) (must yield a Hash).","Set to nil explicitly to clear the proxy rather than assigning an empty string."],"exampleFix":"# before\ncaps.proxy = ENV['HTTP_PROXY']\n\n# after\ncaps.proxy = Selenium::WebDriver::Proxy.new(http: ENV['HTTP_PROXY'])","handlingStrategy":"type-guard","validationCode":"# Validate proxy value before assignment:\nunless proxy.nil? || proxy.is_a?(Hash) || proxy.is_a?(Selenium::WebDriver::Proxy)\n  raise TypeError, 'proxy must be Hash, Proxy, or nil'\nend\ncapabilities.proxy = proxy","typeGuard":"def valid_proxy?(obj)\n  obj.nil? || obj.is_a?(Hash) || obj.is_a?(Selenium::WebDriver::Proxy)\nend","tryCatchPattern":"begin\n  capabilities.proxy = raw_proxy\nrescue TypeError => e\n  capabilities.proxy = Selenium::WebDriver::Proxy.new(http: raw_proxy.to_s)\nend","preventionTips":["Always construct a Proxy object from raw config: Proxy.new(http: value).","When loading proxy from env vars or config files, wrap strings in Proxy.new.","Set proxy to nil explicitly to clear it, never to an empty string or symbol."],"tags":["type-error","proxy","capabilities","type-mismatch"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}