{"record":{"id":"31ba2f801f18e0bd","repo":"SeleniumHQ/selenium","slug":"incompatible-proxy-type-type-inspect-already-s","errorCode":null,"errorMessage":"incompatible proxy type #{type.inspect} (already set to #{@type.inspect})","messagePattern":"incompatible proxy type #(.+?) \\(already set to #(.+?)\\)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"rb/lib/selenium/webdriver/common/proxy.rb","lineNumber":130,"sourceCode":"\n      def socks_password=(value)\n        self.type = :manual\n        @socks_password = value\n      end\n\n      def socks_version=(value)\n        self.type = :manual\n        @socks_version = value\n      end\n\n      def type=(type)\n        unless TYPES.key? type\n          raise ArgumentError,\n                \"invalid proxy type: #{type.inspect}, expected one of #{TYPES.keys.inspect}\"\n        end\n\n        if defined?(@type) && type != @type\n          raise ArgumentError, \"incompatible proxy type #{type.inspect} (already set to #{@type.inspect})\"\n        end\n\n        @type = type\n      end\n\n      def as_json(*)\n        json_result = {\n          'proxyType' => TYPES[type].downcase,\n          'httpProxy' => http,\n          'noProxy' => no_proxy.is_a?(String) ? no_proxy.split(',').map(&:strip).reject(&:empty?) : no_proxy,\n          'proxyAutoconfigUrl' => pac,\n          'sslProxy' => ssl,\n          'autodetect' => auto_detect,\n          'socksProxy' => socks,\n          'socksUsername' => socks_username,\n          'socksPassword' => socks_password,\n          'socksVersion' => socks_version\n        }.compact","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/common/proxy.rb#L112-L148","documentation":"Raised by Selenium::WebDriver::Proxy#type= when a proxy attribute setter implicitly forces a proxy type that conflicts with the type already established by a previous setter. The Proxy object enforces a single proxyType across all attributes: :direct, :manual, :pac, :auto_detect, :system. Each attribute setter (http=, ssl=, socks=, socks_version=, etc.) calls self.type = :manual, while pac= sets :pac and auto_detect= sets :auto_detect. Once one type is set, mixing attributes from a different type family triggers this ArgumentError.","triggerScenarios":"Calling proxy.pac = 'http://...' (sets :pac) followed by proxy.http = 'host:8080' (sets :manual) raises this. Or passing a Hash to Proxy.new that includes both :pac and :http keys (each setter fires during initialize, so the second conflicting one fails). Setting socks_version= after pac= also conflicts (:manual vs :pac).","commonSituations":"Migrating from a manual proxy config to a PAC URL but leaving http/ssl keys in the options hash. Copying proxy examples from different blog posts that use different proxy modes. Building a Proxy from user-supplied config where the user mixes PAC and manual settings.","solutions":["Use only one proxy type family: either manual settings (http, ssl, socks, no_proxy, socks_username, socks_password, socks_version) OR pac URL OR auto_detect OR direct OR system.","If switching proxy modes at runtime, create a new Proxy instance instead of reusing the same one.","Inspect your options Hash before passing it to Proxy.new and remove keys belonging to a different type family.","Set the type explicitly via proxy.type = :manual (or :pac) once, then only set attributes consistent with that type."],"exampleFix":"// before\nproxy = Selenium::WebDriver::Proxy.new(\n  pac: 'http://internal.corp/proxy.pac',\n  http: 'proxy.corp:8080'  # conflicts: forces :manual, but :pac already set\n)\n\n// after\nproxy = Selenium::WebDriver::Proxy.new(\n  pac: 'http://internal.corp/proxy.pac'\n)\n# or, for manual:\nproxy = Selenium::WebDriver::Proxy.new(\n  http: 'proxy.corp:8080',\n  ssl: 'proxy.corp:8080'\n)","handlingStrategy":"validation","validationCode":"# Validate proxy options before constructing Proxy\nVALID_PROXY_KEYS = {\n  manual: %i[http no_proxy ssl socks socks_username socks_password socks_version],\n  pac: %i[pac],\n  auto_detect: %i[auto_detect]\n}.freeze\n\ndef safe_proxy(opts)\n  detected_types = VALID_PROXY_KEYS.select { |_type, keys| (opts.keys & keys).any? }.keys\n  if detected_types.size > 1\n    raise ArgumentError, \"Conflicting proxy types detected: #{detected_types}. Use only one type family.\"\n  end\n  Selenium::WebDriver::Proxy.new(opts)\nend","typeGuard":null,"tryCatchPattern":"begin\n  proxy = Selenium::WebDriver::Proxy.new(proxy_opts)\nrescue ArgumentError => e\n  raise if e.message !~ /incompatible proxy type/\n  # log and fall back to a single-type proxy\n  puts \"Proxy config conflict: #{e.message}. Using manual proxy only.\"\n  proxy = Selenium::WebDriver::Proxy.new(http: proxy_opts[:http], ssl: proxy_opts[:ssl])\nend","preventionTips":["Decide on a single proxy mode (manual, pac, auto_detect, system, direct) before building the options hash.","Document the allowed key sets per proxy type in your config schema.","Use a config validation layer (e.g., dry-validation, dry-schema) to catch conflicting keys before passing to Selenium."],"tags":["proxy","configuration","argument-error","ruby"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}