SeleniumHQ/selenium · error · TypeError

#{device.inspect} is not a valid InputDevice

Error message

#{device.inspect} is not a valid InputDevice

What it means

ActionBuilder#add_input validates that the device is an instance of Interactions::InputDevice. If you pass it a Symbol it first tries to resolve it via Interactions.send(symbol); anything that is still not an InputDevice afterward raises TypeError. This guards the type of devices added to an action sequence.

Source

Thrown at rb/lib/selenium/webdriver/common/action_builder.rb:240

      # Adds pauses for all devices but the given devices
      #
      # @param [Array[InputDevice]] action_devices Array of Input Devices performing an action in this tick.
      #

      def tick(*action_devices)
        return if @async

        @devices.each { |device| device.create_pause unless action_devices.include? device }
      end

      #
      # Adds an InputDevice
      #

      def add_input(device)
        device = Interactions.send(device) if device.is_a?(Symbol) && Interactions.respond_to?(device)

        raise TypeError, "#{device.inspect} is not a valid InputDevice" unless device.is_a?(Interactions::InputDevice)

        unless @async
          max_device = @devices.max { |a, b| a.actions.length <=> b.actions.length }
          pauses(device: device, number: max_device.actions.length) if max_device
        end
        @devices << device
        device
      end
    end # ActionBuilder
  end # WebDriver
end # Selenium

View on GitHub (pinned to aa36b38e69)

Solutions

  1. Pass a known symbol resolvable by Interactions (e.g. :keyboard, :mouse, :wheel, :pen) or an InputDevice instance.
  2. For custom devices, subclass Selenium::WebDriver::Interactions::InputDevice.
  3. If passing a name, use a Symbol not a String.
  4. Construct devices via Interactions APIs (e.g. Interactions.pointer(...)) rather than ad-hoc objects.

Example fix

// before
action_builder.add_input('mouse')
// after
action_builder.add_input(:mouse)
Defensive patterns

Strategy: type-guard

Validate before calling

def input_device?(device)
  device.is_a?(Selenium::WebDriver::Interactions::InputDevice)
end

Type guard

def input_device?(device)
  device.is_a?(Selenium::WebDriver::Interactions::InputDevice)
end

Try / catch

begin
  action_builder.add_input(device)
rescue TypeError => e
  raise unless e.message =~ /not a valid InputDevice/
  action_builder.add_input(device.to_sym)
end

Prevention

When it happens

Trigger: Calling action_builder.add_input(obj) where obj is not an InputDevice and not a resolvable Symbol (e.g. a String, a Hash, nil, or an unrelated object).

Common situations: Passing a string name instead of a symbol, passing a device instance from the wrong library, building a custom device without subclassing Interactions::InputDevice, nil from a failed lookup.

Related errors


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