SeleniumHQ/selenium · error · TypeError

#{source.type} is not a valid input type

Error message

#{source.type} is not a valid input type

What it means

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.

Source

Thrown at rb/lib/selenium/webdriver/common/interactions/pointer_move.rb:47

      class PointerMove < Interaction
        include PointerEventProperties

        VIEWPORT = :viewport
        POINTER = :pointer
        ORIGINS = [VIEWPORT, POINTER].freeze

        def initialize(source, duration, x, y, **opts)
          super(source)
          @duration = duration * 1000
          @x_offset = x
          @y_offset = y
          @origin = opts.delete(:element) || opts.delete(:origin) || :viewport
          @type = :pointerMove
          @opts = opts
        end

        def assert_source(source)
          raise TypeError, "#{source.type} is not a valid input type" unless source.is_a? PointerInput
        end

        def encode
          process_opts.merge('type' => type.to_s,
                             'duration' => @duration.to_i,
                             'x' => @x_offset,
                             'y' => @y_offset,
                             'origin' => @origin)
        end
      end # PointerMove
    end # Interactions
  end # WebDriver
end # Selenium

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Use pointer_input.create_pointer_move(duration:, x:, y:, origin:, **) so the device passes itself as source.
  2. Verify source.is_a?(Selenium::WebDriver::Interactions::PointerInput) before constructing PointerMove.

Example fix

# before
move = Selenium::WebDriver::Interactions::PointerMove.new(wheel_input, 250, 10, 10) # => TypeError

# after
pointer = Selenium::WebDriver::Interactions::PointerInput.new(:mouse)
pointer.create_pointer_move(duration: 250, x: 10, y: 10)
Defensive patterns

Strategy: type-guard

Type guard

def pointer_input?(src)
  src.is_a?(Selenium::WebDriver::Interactions::PointerInput)
end

PointerMove.new(src, dur, x, y, **opts) if pointer_input?(src)

Prevention

When it happens

Trigger: 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.

Common situations: Custom action-builder code that reuses a wheel or key device reference for a move; refactors that swap device variables.

Related errors


AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14). Data as JSON: /api/errors/96f8542cf682b4d2. Report an issue: GitHub.