hashie/hashie · error · ArgumentError
Expected 1-2 arguments, got #{args.length}
Error message
Expected 1-2 arguments, got #{args.length} What it means
Hashie::Rash#fetch is defined as fetch(*args) and enforces its own arity: it raises ArgumentError unless exactly 1 or 2 positional arguments are passed (lib/hashie/rash.rb:66-68), mirroring Ruby's Hash#fetch(key[, default]). Because the signature is a splat, Ruby's native wrong-number-of-arguments check never fires; this explicit guard is the only arity enforcement. The failing call passed 0 arguments or 3 or more.
Source
Thrown at lib/hashie/rash.rb:67
@regexes << key
when Range
@ranges << key
end
@hash[key] = value
end
#
# Return the first thing that matches the key.
#
def [](key)
all(key).first
end
#
# Raise (or yield) unless something matches the key.
#
def fetch(*args)
raise ArgumentError, "Expected 1-2 arguments, got #{args.length}" \
unless (1..2).cover?(args.length)
key, default = args
all(key) do |value|
return value
end
if block_given?
yield key
elsif default
default
else
raise KeyError, "key not found: #{key.inspect}"
end
end
#View on GitHub (pinned to fde8e03a0a)
Solutions
- Call fetch with exactly 1 or 2 arguments: rash.fetch(key) or rash.fetch(key, default).
- If forwarding variable args, destructure first: key, default = args.take(2); then rash.fetch(key, default).
- For a computed fallback, pass a block instead of a third argument: rash.fetch(key) { compute_default } — the block runs only when nothing matches.
- If a miss should not raise, use the nil-returning reader rash[key] instead of fetch.
Example fix
# before args = [query, default, options] value = rash.fetch(*args) # ArgumentError: Expected 1-2 arguments, got 3 # after query, default = args.take(2) value = rash.fetch(query, default)
Defensive patterns
Strategy: validation
Validate before calling
# validate dynamic args before calling Hashie::Rash#fetch
fail ArgumentError, "fetch needs 1-2 args, got #{args.length}" unless (1..2).cover?(args.length)
rash.fetch(*args) Type guard
# Ruby arity predicate for Rash#fetch call sites def rash_fetch_arity_ok?(*args) = (1..2).cover?(args.length)
Try / catch
begin
rash.fetch(*args)
rescue ArgumentError => e
raise unless e.message.start_with?('Expected 1-2 arguments')
rash[args.first] # degrade to the nil-returning reader
end Prevention
- Never splat an unvalidated array into fetch; destructure to exactly key and optional default first.
- Keep dynamic-arity wrappers and extra options away from fetch — its contract is fixed at 1-2 arguments.
- Unit-test delegating code with 0- and 3-argument edge cases.
When it happens
Trigger: Calling rash.fetch() with no arguments; calling rash.fetch(key, default, extra) with three or more arguments; forwarding a runtime-built array rash.fetch(*args) whose length is not 1 or 2; delegators (Forwardable, SimpleDelegator, method_missing proxies) that splat arguments through to fetch.
Common situations: Refactoring code from Hash#fetch into a Rash and leaving an options or third argument in place; wrapper libraries that proxy fetch with extra parameters; test helpers calling fetch with dynamically constructed argument lists.
Related errors
AI-assisted analysis of hashie/hashie@fde8e03a0a (2026-08-23).
Data as JSON: /api/errors/ed1a09d4d3d01fb2.
Report an issue: GitHub.