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

  1. Call fetch with exactly 1 or 2 arguments: rash.fetch(key) or rash.fetch(key, default).
  2. If forwarding variable args, destructure first: key, default = args.take(2); then rash.fetch(key, default).
  3. For a computed fallback, pass a block instead of a third argument: rash.fetch(key) { compute_default } — the block runs only when nothing matches.
  4. 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

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.