puppetlabs/puppet · error · ArgumentError

puppet %{face} %{action} takes %{arg_count} argument, but yo

Error message

puppet %{face} %{action} takes %{arg_count} argument, but you gave %{given_count}

What it means

Before dispatching a face action, FaceBase compares arguments.length with the action's positional_arg_count and raises ArgumentError (singular/plural wording via n_) on mismatch. The displayed counts subtract one on each side because the face name occupies one slot in the raw invocation; the comparison itself is raw length vs arity.

Source

Thrown at lib/puppet/application/face_base.rb:250

    #                   # positional argument!!
    #
    # We could also fix this by making it mandatory to pass the options on
    # every call, but that would make the Ruby API much more annoying to
    # work with; having the defaulting is a much nicer convention to have.
    #
    # We could also pass the arguments implicitly, by having a magic
    # 'options' method that was visible in the scope of the action, which
    # returned the right stuff.
    #
    # That sounds attractive, but adds complications to all sorts of
    # things, especially when you think about how to pass options when you
    # are writing Ruby code that calls multiple faces.  Especially if
    # faces are involved in that. ;)
    #
    # --daniel 2011-04-27
    if (arity = @action.positional_arg_count) > 0
      unless (count = arguments.length) == arity then
        raise ArgumentError, n_("puppet %{face} %{action} takes %{arg_count} argument, but you gave %{given_count}", "puppet %{face} %{action} takes %{arg_count} arguments, but you gave %{given_count}", arity - 1) % { face: @face.name, action: @action.name, arg_count: arity - 1, given_count: count - 1 }
      end
    end

    if @face.deprecated?
      Puppet.deprecation_warning(_("'puppet %{face}' is deprecated and will be removed in a future release") % { face: @face.name })
    end

    result = @face.send(@action.name, *arguments)
    puts render(result, arguments) unless result.nil?
    status = true

  # We need an easy way for the action to set a specific exit code, so we
  # rescue SystemExit here; This allows each action to set the desired exit
  # code by simply calling Kernel::exit.  eg:
  #
  #   exit(2)
  #
  # --kelsey 2012-02-14

View on GitHub (pinned to e227c27540)

Solutions

  1. Run puppet <face> <action> --help and count the POSITIONAL arguments it documents
  2. Adjust the command to pass exactly that many positional words
  3. If arity changed between versions, pin the command syntax to the puppet version you run

Example fix

# before
puppet config set server extra puppet.example.com  # too many arguments

# after
puppet config set server puppet.example.com
Defensive patterns

Strategy: validation

Validate before calling

arity = action.positional_arg_count
raise ArgumentError, "need #{arity} positional args" unless args.length == arity
face.send(action.name, *args)

Prevention

When it happens

Trigger: Any 'puppet <face> <action> ...' where the number of positional words differs from the action's declared arity: 'puppet config set server extra value' (too many), 'puppet config set' (too few). Option flags and their values do not count.

Common situations: Scripts pinning old face syntax across puppet upgrades that changed arity; command lines with an extra pasted word; forgetting that some actions require positional arguments at all.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/874032a6398d4948. Report an issue: GitHub.