SeleniumHQ/selenium · error · ArgumentError
Invalid arguments: #{opts.keys}
Error message
Invalid arguments: #{opts.keys} What it means
Raised by VirtualAuthenticatorOptions#initialize when keyword arguments contain keys other than the six recognized options: :protocol, :transport, :resident_key, :user_verification, :user_consenting, :user_verified. After deleting known keys from the opts hash, any remaining keys trigger ArgumentError listing the unexpected ones.
Source
Thrown at rb/lib/selenium/webdriver/common/virtual_authenticator/virtual_authenticator_options.rb:45
class VirtualAuthenticatorOptions
PROTOCOL = {ctap2: 'ctap2', u2f: 'ctap1/u2f'}.freeze
TRANSPORT = {ble: 'ble', usb: 'usb', nfc: 'nfc', internal: 'internal'}.freeze
attr_accessor :protocol, :transport, :resident_key, :user_verification, :user_consenting, :user_verified
alias resident_key? resident_key
alias user_verification? user_verification
alias user_consenting? user_consenting
alias user_verified? user_verified
def initialize(**opts)
@protocol = opts.delete(:protocol) { :ctap2 }
@transport = opts.delete(:transport) { :usb }
@resident_key = opts.delete(:resident_key) { false }
@user_verification = opts.delete(:user_verification) { false }
@user_consenting = opts.delete(:user_consenting) { true }
@user_verified = opts.delete(:user_verified) { false }
raise ArgumentError, "Invalid arguments: #{opts.keys}" unless opts.empty?
end
#
# @api private
#
def as_json(*)
{'protocol' => PROTOCOL[protocol],
'transport' => TRANSPORT[transport],
'hasResidentKey' => resident_key?,
'hasUserVerification' => user_verification?,
'isUserConsenting' => user_consenting?,
'isUserVerified' => user_verified?}
end
end # VirtualAuthenticatorOptions
end # WebDriver
end # Selenium
View on GitHub (pinned to aa36b38e69)
Solutions
- Use only recognized snake_case keys: protocol:, transport:, resident_key:, user_verification:, user_consenting:, user_verified:.
- Valid values for protocol: :ctap2 (default) or :u2f. For transport: :ble, :usb (default), :nfc, :internal.
- Filter external data before passing: opts.slice(:protocol, :transport, :resident_key, :user_verification, :user_consenting, :user_verified).
Example fix
// before opts = Selenium::WebDriver::VirtualAuthenticatorOptions.new( protoccol: :u2f, # typo hasResidentKey: true, # camelCase userVerification: true # camelCase ) // after opts = Selenium::WebDriver::VirtualAuthenticatorOptions.new( protocol: :u2f, resident_key: true, user_verification: true )
Defensive patterns
Strategy: validation
Validate before calling
VALID_VA_OPTS = %i[protocol transport resident_key user_verification user_consenting user_verified].freeze
def safe_va_options(opts)
unknown = opts.keys - VALID_VA_OPTS
raise ArgumentError, "Unknown VirtualAuthenticatorOptions keys: #{unknown}. Valid: #{VALID_VA_OPTS}" unless unknown.empty?
Selenium::WebDriver::VirtualAuthenticatorOptions.new(**opts)
end Type guard
def valid_va_opts?(opts) (opts.keys - %i[protocol transport resident_key user_verification user_consenting user_verified]).empty? end
Try / catch
begin
va_opts = Selenium::WebDriver::VirtualAuthenticatorOptions.new(**opts)
rescue ArgumentError => e
raise unless e.message.include?('Invalid arguments')
filtered = opts.slice(:protocol, :transport, :resident_key, :user_verification, :user_consenting, :user_verified)
va_opts = Selenium::WebDriver::VirtualAuthenticatorOptions.new(**filtered)
end Prevention
- Use snake_case Ruby kwargs: protocol, transport, resident_key, user_verification, user_consenting, user_verified.
- Do not copy camelCase JSON keys (hasResidentKey, isUserConsenting) directly from the protocol spec.
- Validate protocol (:ctap2, :u2f) and transport (:ble, :usb, :nfc, :internal) values against the PROTOCOL/TRANSPORT constants.
When it happens
Trigger: Calling VirtualAuthenticatorOptions.new(protoccol: :u2f) (typo). Passing :hasResidentKey (camelCase from the JSON spec) instead of :resident_key. Passing :userVerification instead of :user_verification. Passing an unrelated key like :name or :browser.
Common situations: Translating WebAuthn spec JSON fields (camelCase) to Ruby kwargs (snake_case) incorrectly. Typos in option names. Passing a Hash from external/config data without filtering.
Related errors
- Invalid arguments: #{opts.keys}
- could not find extension at #{path.inspect}
- :options must be an instance of #{default_options.class}
- These options are not w3c compliant: #{options}
- expected String or Symbol, got #{key.inspect}:#{key.class}
AI-assisted analysis of SeleniumHQ/selenium@aa36b38e69 (2026-08-14).
Data as JSON: /api/errors/e77081ec685611be.
Report an issue: GitHub.