teamcapybara/capybara · error · ArgumentError
Invalid option #{match.inspect} for :match, should be one of
Error message
Invalid option #{match.inspect} for :match, should be one of #{VALID_MATCH.map(&:inspect).join(', ')} What it means
Capybara::Queries::SelectorQuery#assert_valid_keys validates the :match option on every finder/matcher call. :match controls how Capybara resolves a locator that matches multiple elements (or exactly/inexactly), and only :first, :smart, :prefer_exact, :one are accepted (VALID_MATCH in lib/capybara/queries/selector_query.rb:13). Any other value raises ArgumentError before the DOM is searched, so this fails fast on the first query that uses it.
Source
Thrown at lib/capybara/queries/selector_query.rb:347
filters
end
def ordered_results(results)
case @order
when :reverse
results.reverse
else
results
end
end
def custom_keys
@custom_keys ||= node_filters.keys + expression_filters.keys
end
def assert_valid_keys
unless VALID_MATCH.include?(match)
raise ArgumentError, "Invalid option #{match.inspect} for :match, should be one of #{VALID_MATCH.map(&:inspect).join(', ')}"
end
unhandled_options = @options.keys.reject do |option_name|
valid_keys.include?(option_name) ||
expression_filters.any? { |_name, ef| ef.handles_option? option_name } ||
node_filters.any? { |_name, nf| nf.handles_option? option_name }
end
return if unhandled_options.empty?
invalid_names = unhandled_options.map(&:inspect).join(', ')
valid_names = (valid_keys - [:allow_self]).map(&:inspect).join(', ')
raise ArgumentError, "Invalid option(s) #{invalid_names}, should be one of #{valid_names}"
end
def filtered_expression(expr)
conditions = {}
conditions[:id] = options[:id] if use_default_id_filter?View on GitHub (pinned to 15b5fdb76e)
Solutions
- Change the value to one of the four accepted symbols: :first, :smart, :prefer_exact, or :one (most common fix is the :smartest -> :smart typo).
- Drop the :match option entirely to use the default (:smart).
- If you wanted 'any match is fine, take the first', use first('selector') or match: :first instead of inventing a value.
- Set it globally with Capybara.match = :first in your setup instead of passing per-call values that drift from the allowed set.
Example fix
# before
find('.item', match: :smartest)
# after
find('.item', match: :smart) Defensive patterns
Strategy: validation
Validate before calling
VALID_MATCH = %i[first smart prefer_exact one].freeze
match_value = :smart # from config/ENV
raise ArgumentError, "bad :match #{match_value}" unless VALID_MATCH.include?(match_value)
find('.item', match: match_value) Type guard
def valid_match?(value) %i[first smart prefer_exact one].include?(value) end
Prevention
- Keep :match values in a single constant in spec_support and validate it at boot when it comes from ENV/config.
- Assert on the four allowed symbols in helper unit tests when the value is user-configurable.
When it happens
Trigger: Calling any query API that forwards options to SelectorQuery with a bad :match symbol: find('.item', match: :smartest), all('tr', match: :all), first('td', match: :any), have_selector('.x', match: :exact), find(:id, 'foo', match: :one_of) - all raise immediately in assert_valid_keys.
Common situations: Typos (:smartest instead of :smart), copying :match values from other libraries (RSpec's :any, minitest's :one!), or a shared helper/spec_support file hardcoding a value that a Capybara upgrade renamed. Also hit when interpolating a configurable match value from an environment variable without validating it.
Related errors
- Invalid option(s) #{invalid_names}, should be one of #{valid
- #{@type} is not a valid type for a text query
- redirected more than #{driver.redirect_limit} times, check f
- rack-test requires a rack application, but none was given
- This driver doesn't support case insensitive attribute match
AI-assisted analysis of teamcapybara/capybara@15b5fdb76e (2026-08-21).
Data as JSON: /api/errors/d059246c2f5f2c29.
Report an issue: GitHub.