SeleniumHQ/selenium · error · ArgumentError
expected #{arr.inspect} to have 2 elements
Error message
expected #{arr.inspect} to have 2 elements What it means
Raised by SearchContext#extract_args when a single Hash argument is passed to find_element/find_elements but the shifted key-value pair does not yield exactly 2 elements. This is an internal consistency check after calling Hash#shift on a duplicated hash; it should always produce a [key, value] pair of size 2. Encountering this error implies the argument was an Array or custom object whose #shift returned something unexpected.
Source
Thrown at rb/lib/selenium/webdriver/common/search_context.rb:105
end
private
def extract_args(args)
case args.size
when 2
args
when 1
arg = args.first
unless arg.respond_to?(:shift)
raise ArgumentError,
"expected #{arg.inspect}:#{arg.class} to respond to #shift"
end
# this will be a single-entry hash, so use #shift over #first or #[]
arr = arg.dup.shift
raise ArgumentError, "expected #{arr.inspect} to have 2 elements" unless arr.size == 2
arr
else
raise ArgumentError, "wrong number of arguments (#{args.size} for 2)"
end
end
end # SearchContext
end # WebDriver
end # Selenium
View on GitHub (pinned to aa36b38e69)
Solutions
- Pass a well-formed two-element array: find_element([:css, '#my-id']).
- Or use the Hash form: find_element(css: '#my-id').
- Validate the locator structure before passing it if building dynamically.
Example fix
// before strategy = [:css] element = driver.find_element(strategy) # only 1 element // after strategy = [:css, '#my-id'] element = driver.find_element(strategy)
Defensive patterns
Strategy: validation
Validate before calling
def build_locator(how, what)
[how, what].tap do |arr|
raise ArgumentError, 'Locator must have exactly 2 elements' unless arr.size == 2
end
end
# usage: driver.find_element(build_locator(:css, '#id')) Type guard
def valid_two_element_array?(arr) arr.is_a?(Array) && arr.size == 2 end
Try / catch
begin
driver.find_element(locator)
rescue ArgumentError => e
raise unless e.message.include?('to have 2 elements')
raise ArgumentError, "Locator array malformed: #{locator.inspect}. Expected [strategy, value]."
end Prevention
- Prefer the Hash form find_element(css: '#id') or two-arg form find_element(:css, '#id') over raw arrays.
- When constructing locator arrays programmatically, assert size == 2 before use.
- Avoid find_element(*dynamic_array) where dynamic_array could have unexpected sizes.
When it happens
Trigger: Passing a single Array like find_element([:css]) (size 1) instead of find_element([:css, '#id']) (size 2). Passing a custom object that responds to #shift but returns an array of size != 2. Passing an empty Hash find_element({}) where shift returns nil.
Common situations: Constructing a locator array dynamically and accidentally producing a malformed array. Passing a multi-key Hash (only the first key is used via shift, but if values are themselves arrays the size check can be confused).
Related errors
- cannot find element by #{how.inspect}
- expected #{arg.inspect}:#{arg.class} to respond to #shift
- wrong number of arguments (#{args.size} for 2)
- incompatible proxy type #{type.inspect} (already set to #{@t
- cannot find elements by #{how.inspect}
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/12d1c5f87f6e1cde.
Report an issue: GitHub.