{"record":{"id":"838a244051758459","repo":"SeleniumHQ/selenium","slug":"opts-inspect-invalid-for-command-inspect","errorCode":null,"errorMessage":"#{opts.inspect} invalid for #{command.inspect}","messagePattern":"#(.+?) invalid for #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"rb/lib/selenium/webdriver/remote/bridge.rb","lineNumber":627,"sourceCode":"\n        private\n\n        #\n        # executes a command on the remote server.\n        #\n        # @return [WebDriver::Remote::Response]\n        #\n\n        def execute(command, opts = {}, command_hash = nil)\n          verb, path = commands(command) || raise(ArgumentError, \"unknown command: #{command.inspect}\")\n          path = path.dup\n\n          path[':session_id'] = session_id if path.include?(':session_id')\n\n          begin\n            opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s) }\n          rescue IndexError\n            raise ArgumentError, \"#{opts.inspect} invalid for #{command.inspect}\"\n          end\n\n          WebDriver.logger.debug(\"-> #{verb.to_s.upcase} #{path}\", id: :command)\n          http.call(verb, path, command_hash)['value']\n        end\n\n        def escaper\n          @escaper ||= defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::DEFAULT_PARSER\n        end\n\n        def commands(command)\n          command_list[command] || Bridge.extra_commands[command]\n        end\n\n        def unwrap_script_result(arg)\n          case arg\n          when Array\n            arg.map { |e| unwrap_script_result(e) }","sourceCodeStart":609,"sourceCodeEnd":645,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/remote/bridge.rb#L609-L645","documentation":"Raised by Bridge#execute when the opts hash passed to a command contains a placeholder key that does not exist in that command's URL path template. The bridge iterates opts and substitutes each key.inspect (e.g. ':window_handle') into the path string via String#[]=; when the placeholder is absent Ruby raises IndexError, which is rescued and re-raised as this ArgumentError. It signals a mismatch between the command's registered path and the parameters the caller supplied.","triggerScenarios":"Calling bridge.execute(:some_command, {extra_key: 'val}) where :some_command's path template (from commands(command) or Bridge.extra_commands) does not contain the ':extra_key' placeholder. Also triggered when a custom command is registered via add_commands with a path missing a placeholder that the caller then passes in opts. Passing the wrong command symbol whose path expects different placeholders than the opts provided.","commonSituations":"Registering a custom BiDi or vendor extension command with a path template like '/session/:session_id/foo' but then calling execute with opts keys that don't match. Mistyping a placeholder key in opts (e.g. ':windowHandle' vs ':window_handle'). Using a command symbol that was never registered (though that hits the 'unknown command' raise first). Version changes that rename path placeholders without updating caller code.","solutions":["Inspect the command's registered path template in the commands hash (or Bridge.extra_commands) and ensure every key in opts has a matching ':key' placeholder in the path.","Remove any opts keys that have no corresponding placeholder in the path, or add the missing placeholder to the path template when registering the command.","If using a custom command via add_commands, double-check the path string uses ':session_id' and any other ':symbol' placeholders exactly as they appear as Symbol keys in opts.","Enable debug logging (WebDriver.logger.level = :debug, id: :command) to see the verb and path being built before the substitution fails."],"exampleFix":"# before\nbridge.execute(:my_custom_cmd, {window: 'win1', extra: 'x'})\n# path is \"/session/:session_id/custom\" -> :window and :extra have no placeholder\n\n# after\nbridge.add_commands({my_custom_cmd: [:post, '/session/:session_id/window/:window']})\nbridge.execute(:my_custom_cmd, {window: 'win1'})","handlingStrategy":"validation","validationCode":"# Before calling execute on a custom command, validate opts keys match the path template:\npath_template = bridge.commands(command_name)&.last\nexpected_placeholders = path_template&.scan(/:(\\w+)/)&.flatten&.map(&:to_sym)\nextra_keys = opts.keys - expected_placeholders\nraise ArgumentError, \"opts contain keys with no placeholder: #{extra_keys}\" unless extra_keys.empty?","typeGuard":"# Confirm all opts keys are Symbols that appear as ':name' in the path:\ndef valid_execute_opts?(command, opts, bridge)\n  path = bridge.commands(command)&.last\n  return false unless path\n  placeholders = path.scan(/:(\\w+)/).flatten.map(&:to_sym)\n  opts.keys.all? { |k| k.is_a?(Symbol) && placeholders.include?(k) }\nend","tryCatchPattern":"begin\n  bridge.execute(:my_command, {key: 'val'})\nrescue ArgumentError => e\n  WebDriver.logger.warn(\"Command path mismatch: #{e.message}\", id: :command)\n  # inspect bridge.commands(:my_command) and adjust opts or re-register the command\nend","preventionTips":["When registering custom commands, document the expected opts keys next to the path template.","Use Symbol keys consistently for opts — the path uses key.inspect which includes the colon.","Write a unit test that calls each custom command with its expected opts to catch mismatches early."],"tags":["argument-error","url-building","bridge","custom-commands"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}