teamcapybara/capybara · error · ArgumentError
Unused parameters passed to #{self.class.name} : #{args}
Error message
Unused parameters passed to #{self.class.name} : #{args} What it means
SelectorQuery#initialize consumes the optional selector name (symbol), then the locator, and raises ArgumentError 'Unused parameters passed ...' if any positional arguments remain. It fires at query construction, before searching, and is the library's guard against calling find/all with more positionals than the (selector, locator) shape allows — extra constraints must be keyword options, not extra strings.
Source
Thrown at lib/capybara/queries/selector_query.rb:52
end
super(@options)
self.session_options = session_options
@selector = Selector.new(
find_selector(args[0].is_a?(Symbol) ? args.shift : args[0]),
config: {
enable_aria_label: enable_aria_label,
enable_aria_role: enable_aria_role,
test_id: test_id
},
format: selector_format
)
@locator = args.shift
@filter_block = filter_block
raise ArgumentError, "Unused parameters passed to #{self.class.name} : #{args}" unless args.empty?
@expression = selector.call(@locator, **@options)
warn_exact_usage
assert_valid_keys
end
def name; selector.name; end
def label; selector.label || selector.name; end
def description(only_applied = false) # rubocop:disable Style/OptionalBooleanParameter
desc = +''
show_for = show_for_stage(only_applied)
if show_for[:any]
desc << 'visible ' if visible == :visible
desc << 'non-visible ' if visible == :hiddenView on GitHub (pinned to 15b5fdb76e)
Solutions
- Convert extra positionals to keyword options: find('div', text: 'some text')
- If building args dynamically, keep it to [kind, locator] and pass the rest as **options
- Read the message: it prints the exact leftover args (#{args}) so you can see which call site produced them
- For multiple alternatives use assert_any_of_selectors or a joined XPath/CSS, not extra parameters
Example fix
# before
find('div', 'Welcome')
# after
find('div', text: 'Welcome') Defensive patterns
Strategy: validation
Validate before calling
raise ArgumentError, 'pass filters as keywords' unless args.last.is_a?(Hash) || args.size <= 2 find(*args.take(2), **opts)
Type guard
def valid_find_args?(args) args.size <= 2 && args.first.nil? || args.first.is_a?(Symbol) || args.size <= 2 end
Try / catch
begin
find(*args)
rescue ArgumentError => e
raise unless e.message.start_with?('Unused parameters')
find(args[0], args[1], **opts) # leftover positionals were meant as filters
end Prevention
- Always pass filters as keywords: text:, visible:, id: — not extra positionals
- Keep dynamic arg arrays to [kind, locator] and splat options separately
- Read the echoed leftover args in the message to find the bad call site
When it happens
Trigger: find('div', 'some text') where the second string should be text: 'some text'; find(:css, 'li', 'extra') after splatting a mis-built array (find(*['css', 'li', 'oops'])); passing two locators hoping for OR semantics; helper methods doing find(*args) where args contains leftovers; using :xpath with multiple path strings.
Common situations: Forgetting the keyword form for filters, dynamic locator arrays with unexpected extra entries, migrating from other libraries where extra positionals are allowed, Ruby 3 kwargs separation turning a trailing hash into a positional in some call shapes (then the hash itself is reported as unused).
Related errors
- Invalid option(s) #{invalid_names}, should be one of #{valid
- You must specify both x: and y: for a click offset
- Ambiguous match, found #{result.size} elements matching #{qu
- Unable to find #{query.applied_description}
- result.failure_message
AI-assisted analysis of teamcapybara/capybara@15b5fdb76e (2026-08-21).
Data as JSON: /api/errors/4d3ffc5fee68afc0.
Report an issue: GitHub.