{"record":{"id":"f5bb6bf55cf78098","repo":"SeleniumHQ/selenium","slug":"invalid-arguments-opts-keys","errorCode":null,"errorMessage":"Invalid arguments: #{opts.keys}","messagePattern":"Invalid arguments: #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"rb/lib/selenium/webdriver/common/interactions/scroll.rb","lineNumber":40,"sourceCode":"    module Interactions\n      #\n      # Action related to scrolling a wheel.\n      #\n      # @api private\n      #\n\n      class Scroll < Interaction\n        def initialize(source:, origin: :viewport, duration: 0.25, **opts)\n          super(source)\n          @type = :scroll\n          @duration = duration * 1000\n          @origin = origin\n          @x_offset = opts.delete(:x) || 0\n          @y_offset = opts.delete(:y) || 0\n          @delta_x = opts.delete(:delta_x) || 0\n          @delta_y = opts.delete(:delta_y) || 0\n\n          raise ArgumentError, \"Invalid arguments: #{opts.keys}\" unless opts.empty?\n        end\n\n        def assert_source(source)\n          raise TypeError, \"#{source.type} is not a valid input type\" unless source.is_a? WheelInput\n        end\n\n        def encode\n          {'type' => type.to_s,\n           'duration' => @duration.to_i,\n           'x' => @x_offset,\n           'y' => @y_offset,\n           'deltaX' => @delta_x,\n           'deltaY' => @delta_y,\n           'origin' => @origin.is_a?(Element) ? @origin : @origin.to_s}\n        end\n      end # PointerPress\n    end # Interactions\n  end # WebDriver","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/common/interactions/scroll.rb#L22-L58","documentation":"Raised as ArgumentError by Scroll#initialize when, after extracting the recognized kwargs (:x, :y, :delta_x, :delta_y), the remaining opts hash is non-empty. Recognized Scroll kwargs are: source (required), origin, duration, x, y, delta_x, delta_y. Anything else is rejected.","triggerScenarios":"Calling wheel.create_scroll(...) or the public scroll/scroll_by/scroll_from/scroll_to DSL with an unrecognized key — e.g. scroll_by(100, 200, dx: 0) (should be delta_x:), scroll(deltaX: 100) (string key, or camelCase), or scroll_from(origin, 0, 200, speed: 5).","commonSituations":"camelCase vs snake_case confusion (deltaX vs delta_x); passing x/y to scroll_by (which takes delta_x/delta_y); typos; copy-paste from a JS example.","solutions":["Use only the recognized keys: origin, duration, x, y, delta_x, delta_y (plus source internally).","For scroll_by use delta_x:/delta_y:; for scroll_from pass x:/y: via ScrollOrigin offsets and delta_x:/delta_y: for the scroll amount.","Check for camelCase leaks — convert deltaX→delta_x, deltaY→delta_y."],"exampleFix":"# before\ndriver.action.scroll_by(100, 200, speed: 5).perform # => ArgumentError: Invalid arguments: [:speed]\n# or\ndriver.action.scroll(deltaX: 100, deltaY: 200).perform # => ArgumentError: Invalid arguments: [:deltaX]\n\n# after\ndriver.action.scroll_by(100, 200).perform","handlingStrategy":"validation","validationCode":"ALLOWED = %i[source origin duration x y delta_x delta_y].freeze\nunknown = opts.keys - ALLOWED\nraise \"unsupported scroll opts: #{unknown}\" unless unknown.empty?\n\ndriver.action.scroll(**opts.slice(*ALLOWED)).perform","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use snake_case kwargs: delta_x/delta_y (not deltaX/deltaY), and the right method per intent (scroll_by takes delta_x/delta_y).","Do not pass unrelated options like speed/deceleration to the scroll DSL."],"tags":["interactions","wheel-scroll","argument-validation","ruby"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}