{"record":{"id":"96f8542cf682b4d2","repo":"SeleniumHQ/selenium","slug":"source-type-is-not-a-valid-input-type-96f854","errorCode":null,"errorMessage":"#{source.type} is not a valid input type","messagePattern":"#(.+?) is not a valid input type","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"rb/lib/selenium/webdriver/common/interactions/pointer_move.rb","lineNumber":47,"sourceCode":"      class PointerMove < Interaction\n        include PointerEventProperties\n\n        VIEWPORT = :viewport\n        POINTER = :pointer\n        ORIGINS = [VIEWPORT, POINTER].freeze\n\n        def initialize(source, duration, x, y, **opts)\n          super(source)\n          @duration = duration * 1000\n          @x_offset = x\n          @y_offset = y\n          @origin = opts.delete(:element) || opts.delete(:origin) || :viewport\n          @type = :pointerMove\n          @opts = opts\n        end\n\n        def assert_source(source)\n          raise TypeError, \"#{source.type} is not a valid input type\" unless source.is_a? PointerInput\n        end\n\n        def encode\n          process_opts.merge('type' => type.to_s,\n                             'duration' => @duration.to_i,\n                             'x' => @x_offset,\n                             'y' => @y_offset,\n                             'origin' => @origin)\n        end\n      end # PointerMove\n    end # Interactions\n  end # WebDriver\nend # Selenium\n","sourceCodeStart":29,"sourceCodeEnd":61,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/common/interactions/pointer_move.rb#L29-L61","documentation":"Raised as TypeError by PointerMove#assert_source when the source passed to PointerMove.new(source, duration, x, y, **opts) is not a PointerInput. PointerMove encodes a W3C pointerMove action and is only valid on a pointer source. Note PointerMove mixes in PointerEventProperties, so unknown opts there raise error 385 instead.","triggerScenarios":"Constructing Interactions::PointerMove.new(source, ...) with source being a KeyInput, WheelInput, NoneInput, or non-InputDevice. Reached via PointerInput#create_pointer_move (which always passes self) or by direct construction with the wrong device.","commonSituations":"Custom action-builder code that reuses a wheel or key device reference for a move; refactors that swap device variables.","solutions":["Use pointer_input.create_pointer_move(duration:, x:, y:, origin:, **) so the device passes itself as source.","Verify source.is_a?(Selenium::WebDriver::Interactions::PointerInput) before constructing PointerMove."],"exampleFix":"# before\nmove = Selenium::WebDriver::Interactions::PointerMove.new(wheel_input, 250, 10, 10) # => TypeError\n\n# after\npointer = Selenium::WebDriver::Interactions::PointerInput.new(:mouse)\npointer.create_pointer_move(duration: 250, x: 10, y: 10)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def pointer_input?(src)\n  src.is_a?(Selenium::WebDriver::Interactions::PointerInput)\nend\n\nPointerMove.new(src, dur, x, y, **opts) if pointer_input?(src)","tryCatchPattern":null,"preventionTips":["Use pointer_input.create_pointer_move(...) instead of constructing PointerMove directly.","Keep move actions wired only to PointerInput instances."],"tags":["interactions","pointer-move","assert-source","internal-api","ruby"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}