teamcapybara/capybara · error · ArgumentError

Unknown keys type

Error message

Unknown keys type

What it means

Raised by _send_keys in the Selenium Safari node when a value sent to an element is not a String, Symbol, or Array. The dispatcher case-matches those three types and everything else (Integer, Float, nil, Hash) falls into the else branch with 'Unknown keys type'.

Source

Thrown at lib/capybara/selenium/nodes/safari_node.rb:108

private

  def _send_keys(keys, actions = browser_action, down_keys = ModifierKeysStack.new)
    case keys
    when *MODIFIER_KEYS
      down_keys.press(keys)
      actions.key_down(keys)
    when String
      keys = keys.upcase if down_keys&.include?(:shift)
      actions.send_keys(keys)
    when Symbol
      actions.send_keys(keys)
    when Array
      down_keys.push
      keys.each { |sub_keys| _send_keys(sub_keys, actions, down_keys) }
      down_keys.pop.reverse_each { |key| actions.key_up(key) }
    else
      raise ArgumentError, 'Unknown keys type'
    end
    actions
  end

  MODIFIER_KEYS = %i[control left_control right_control
                     alt left_alt right_alt
                     shift left_shift right_shift
                     meta left_meta right_meta
                     command].freeze
end

View on GitHub (pinned to 15b5fdb76e)

Solutions

  1. Convert before sending: find('#pin').send_keys(pin.to_s)
  2. Send special keys as symbols: send_keys('text', :enter) or send_keys([:shift, 'a'])
  3. Centralize input in a helper that coerces: def type_into(el, val) el.send_keys(String(val)) end

Example fix

# before
find('#pin').set(1234)

# after
find('#pin').set(1234.to_s)
Defensive patterns

Strategy: type-guard

Validate before calling

def valid_keys?(k)
  case k
  when String, Symbol then true
  when Array then k.all? { |sub| valid_keys?(sub) }
  else false
  end
end

find('#pin').send_keys(value) if valid_keys?(value)

Type guard

def coerce_keys(k)
  case k
  when String, Symbol, Array then k
  else k.to_s
  end
end

find('#pin').send_keys(coerce_keys(user_pin))

Try / catch

begin
  el.send_keys(value)
rescue ArgumentError => e
  raise unless e.message == 'Unknown keys type'
  el.send_keys(value.to_s)
end

Prevention

When it happens

Trigger: find('#pin').send_keys(1234) or el.set(42) on the selenium_safari driver; send_keys(nil); arrays mixing invalid members such as [1, :enter]; passing keycodes as integers copied from other driver APIs.

Common situations: Passing numeric values from factories, Faker, or Cucumber step tables straight to send_keys; porting specs from rack_test (which stringifies input) to selenium; translating Java/JS sendKeys examples that use char codes literally.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


AI-assisted analysis of teamcapybara/capybara@15b5fdb76e (2026-08-21). Data as JSON: /api/errors/1fbd9115cf2a93b9. Report an issue: GitHub.