{"record":{"id":"6595c620ff5557be","repo":"SeleniumHQ/selenium","slug":"capabilities-parameter-only-accepts-objects-respo","errorCode":null,"errorMessage":":capabilities parameter only accepts objects responding to #as_json which #{cap.class} does not","messagePattern":":capabilities parameter only accepts objects responding to #as_json which #(.+?) does not","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"rb/lib/selenium/webdriver/remote/driver.rb","lineNumber":85,"sourceCode":"        end\n\n        def process_options(options, capabilities)\n          if options && capabilities\n            msg = \"Don't use both :options and :capabilities when initializing #{self.class}, prefer :options\"\n            raise ArgumentError, msg\n          elsif options.nil? && capabilities.nil?\n            raise ArgumentError, \"#{self.class} needs :options to be set\"\n          end\n          options ? options.as_json : generate_capabilities(capabilities)\n        end\n\n        def generate_capabilities(capabilities)\n          Array(capabilities).map { |cap|\n            if cap.is_a? Symbol\n              cap = WebDriver::Options.send(cap)\n            elsif !cap.respond_to? :as_json\n              msg = \":capabilities parameter only accepts objects responding to #as_json which #{cap.class} does not\"\n              raise ArgumentError, msg\n            end\n            cap.as_json\n          }.inject(:merge)\n        end\n      end # Driver\n    end # Remote\n  end # WebDriver\nend # Selenium\n","sourceCodeStart":67,"sourceCodeEnd":94,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/remote/driver.rb#L67-L94","documentation":"Raised by Remote::Driver#generate_capabilities when an element of the :capabilities array does not respond to #as_json. The method iterates the array, resolves Symbols to Options via WebDriver::Options.send(cap), and calls cap.as_json on everything else to produce the JSON capabilities payload; objects without as_json cannot be serialized for the W3C new-session request.","triggerScenarios":"Passing capabilities: [some_string] or capabilities: [an_integer]. Passing a raw Hash inside the array (Hash does respond to as_json via the JSON gem, so this typically triggers for truly non-serializable objects). Passing a custom class instance that doesn't implement as_json. Passing a Capabilities object from an incompatible library version.","commonSituations":"Using the legacy :capabilities array API with objects that were valid in Selenium 3 but whose as_json contract changed. Passing driver-specific config objects instead of Options/Capabilities. Mixed-up capability arrays containing strings parsed from config files.","solutions":["Use Symbols that map to Options: capabilities: [:chrome] (resolved via WebDriver::Options.send).","Use Options or Capabilities objects that implement as_json: capabilities: [Selenium::WebDriver::Options.chrome].","If passing custom objects, ensure they implement a valid #as_json method returning a Hash.","Migrate to the :options parameter which is type-checked and clearer."],"exampleFix":"# before\ndriver = Selenium::WebDriver.for(:remote, url: url,\n  capabilities: [{browserName: 'chrome'}])  # raw hash may fail depending on JSON gem\n\n# after\ndriver = Selenium::WebDriver.for(:remote, url: url,\n  options: Selenium::WebDriver::Options.chrome)","handlingStrategy":"type-guard","validationCode":"# Validate each capability object before passing:\ncaps_array.each do |cap|\n  next if cap.is_a?(Symbol)\n  raise ArgumentError, \"#{cap.class} does not respond to #as_json\" unless cap.respond_to?(:as_json)\nend","typeGuard":"def valid_capabilities_array?(arr)\n  arr.all? { |c| c.is_a?(Symbol) || c.respond_to?(:as_json) }\nend","tryCatchPattern":"begin\n  Selenium::WebDriver.for(:remote, url: url, capabilities: caps)\nrescue ArgumentError\n  # fall back to :options with a single Options object\n  Selenium::WebDriver.for(:remote, url: url, options: Selenium::WebDriver::Options.chrome)\nend","preventionTips":["Migrate from :capabilities arrays to the single :options parameter.","If using :capabilities, only pass Symbols or Options/Capabilities objects.","Do not put raw Hashes or Strings in the capabilities array."],"tags":["argument-error","capabilities","serialization","as-json"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}