SeleniumHQ/selenium · error · ArgumentError
cannot find element by #{how.inspect}
Error message
cannot find element by #{how.inspect} What it means
Raised by SearchContext#find_element when the 'how' (locator strategy key) is not found in the FINDERS registry. The valid strategies are: :class, :class_name, :css, :id, :link, :link_text, :name, :partial_link_text, :relative, :tag_name, :xpath (plus any registered via SearchContext.extra_finders). Passing a typo, a string that doesn't match a registered symbol, or an unsupported strategy raises ArgumentError.
Source
Thrown at rb/lib/selenium/webdriver/common/search_context.rb:69
# the entire document, not just the children of this current node. Use
# ".//" to limit your search to the children of the receiving Element.
#
# @overload find_element(how, what)
# @param [Symbol, String] how The method to find the element by
# @param [String] what The locator to use
# @overload find_element(opts)
# @param [Hash] opts Find options
# @option opts [Symbol] :how Key named after the method to find the element by, containing the locator
# @return [Element]
#
# @raise [Error::NoSuchElementError] if the element doesn't exist
#
def find_element(*args)
how, what = extract_args(args)
by = SearchContext.finders[how.to_sym]
raise ArgumentError, "cannot find element by #{how.inspect}" unless by
bridge.find_element_by by, what, ref
end
#
# Find all elements matching the given arguments
#
# @see SearchContext#find_element
#
def find_elements(*args)
how, what = extract_args(args)
by = SearchContext.finders[how.to_sym]
raise ArgumentError, "cannot find elements by #{how.inspect}" unless by
bridge.find_elements_by by, what, ref
endView on GitHub (pinned to aa36b38e69)
Solutions
- Use one of the registered symbols: :class, :class_name, :css, :id, :link, :link_text, :name, :partial_link_text, :relative, :tag_name, :xpath.
- For CSS selectors use :css (not :css_selector or the string 'css selector').
- For class name use :class or :class_name (not :classname).
- For tag name use :tag_name (not :tag).
- If you need a custom strategy, register it via Selenium::WebDriver::SearchContext.extra_finders = { my_strategy: 'my strategy' } before using it.
Example fix
// before
element = driver.find_element(:classname, 'submit-btn')
element = driver.find_element('css selector', '#login')
// after
element = driver.find_element(:class, 'submit-btn')
element = driver.find_element(:css, '#login') Defensive patterns
Strategy: type-guard
Validate before calling
VALID_FINDERS = %i[
class class_name css id link link_text name
partial_link_text relative tag_name xpath
].freeze
def safe_find_element(driver, how, what)
raise ArgumentError, "Unsupported finder: #{how.inspect}" unless VALID_FINDERS.include?(how.to_sym)
driver.find_element(how, what)
end Type guard
def valid_locator_strategy?(how) Selenium::WebDriver::SearchContext.finders.key?(how.to_sym) end
Try / catch
begin
driver.find_element(how, what)
rescue ArgumentError => e
raise unless e.message.include?('cannot find element by')
# fall back to a default strategy or re-raise with context
raise ArgumentError, "Invalid locator strategy '#{how}'. Valid: #{Selenium::WebDriver::SearchContext.finders.keys}"
end Prevention
- Centralize locator strategy constants in your test framework instead of inlining symbols.
- Use the Selenium::WebDriver::SearchContext.finders.keys list to validate dynamically-supplied strategies.
- Avoid passing raw strings from external config as strategies; always .to_sym and validate.
When it happens
Trigger: Calling find_element(:class, 'btn') works, but find_element(:classname, 'btn') (no underscore) fails because :classname is not registered. Passing find_element(:tag, 'div') instead of :tag_name. Passing a plain string like find_element('css selector', 'div') where 'css selector' is not a key (use :css instead). Using a custom finder that was never registered via extra_finders.
Common situations: Copy-pasting CSS selector strategy strings from the W3C protocol spec ('css selector') instead of using the Ruby symbol (:css). Typos in locator strategy symbols. Code written against a different Selenium language binding (e.g., Python uses By.CSS_SELECTOR) ported incorrectly to Ruby.
Related errors
- cannot find elements by #{how.inspect}
- expected #{arg.inspect}:#{arg.class} to respond to #shift
- expected #{arr.inspect} to have 2 elements
- wrong number of arguments (#{args.size} for 2)
- incompatible proxy type #{type.inspect} (already set to #{@t
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/e16048e566fbb023.
Report an issue: GitHub.