puppetlabs/puppet · error · ArgumentError

The legacy subcommand '%{sub_command}' does not support supp

Error message

The legacy subcommand '%{sub_command}' does not support supplying an action

What it means

Raised by the `puppet help` Face when the first argument names a legacy (non-Face) application and a second argument (an action name) is also given. Legacy applications (everything in Puppet::Application.available_application_names that is not a Face stub, e.g. agent, apply, describe) pre-date Faces and expose no actions, so `puppet help <legacy-app> <action>` cannot be resolved. Puppet raises ArgumentError before rendering any help text.

Source

Thrown at lib/puppet/face/help.rb:62

      if args.length > 2
        # TRANSLATORS 'puppet help' is a command line and should not be translated
        raise ArgumentError, _("The 'puppet help' command takes two (optional) arguments: a subcommand and an action")
      end

      version = :current
      if options.has_key? :version
        if options[:version].to_s !~ /^current$/i
          version = options[:version]
        elsif args.length == 0
          raise ArgumentError, _("Supplying a '--version' only makes sense when a Faces subcommand is given")
          # TRANSLATORS '--version' is a command line option and should not be translated
        end
      end

      facename, actionname = args
      if legacy_applications.include? facename
        if actionname
          raise ArgumentError, _("The legacy subcommand '%{sub_command}' does not support supplying an action") % { sub_command: facename }
        end

        # legacy apps already emit ronn output
        return render_application_help(facename)
      elsif options[:ronn]
        render_face_man(facename || :help)
      # Calling `puppet help <app> --ronn` normally calls this action with
      # <app> as the first argument in the `args` array. However, if <app>
      # happens to match the name of an action, like `puppet help help
      # --ronn`, then face_base "eats" the argument and `args` will be
      # empty. Rather than force users to type `puppet help help help
      # --ronn`, default the facename to `:help`
      else
        render_face_help(facename, actionname, version)
      end
    end
  end

View on GitHub (pinned to e227c27540)

Solutions

  1. Drop the action argument: run `puppet help <legacy-app>` to print that application's help
  2. Get flag-level help directly from the application: `puppet <legacy-app> --help`
  3. If you need action syntax, check `puppet help` output for the Face equivalent of the subcommand and use that name
  4. In Ruby code, strip the action argument when the face name is a legacy application before calling the help face

Example fix

# before
puppet help agent certificate
# after
puppet help agent
puppet agent --help
Defensive patterns

Strategy: validation

Validate before calling

require 'puppet/application'
face, action =ARGV[0], ARGV[1]
legacy = Puppet::Application.available_application_names.reject { |a| Puppet::Face.face?(a) rescue false }
action = nil if action && legacy.include?(face)
Puppet::Face[:help, :current].call(*[face, action].compact)

Try / catch

begin
  Puppet::Face[:help, :current].call(*args)
rescue ArgumentError => e
  warn e.message
  args = [args.first] # retry with the face name only
  Puppet::Face[:help, :current].call(*args)
end

Prevention

When it happens

Trigger: Running `puppet help agent <something>` or `puppet help describe <action>`; calling Puppet::Face[:help, :current].call(facename, actionname) where facename is in the legacy_applications list and actionname is non-nil; wrapper scripts that blindly append an action name to every `puppet help X` invocation.

Common situations: Users assuming every subcommand supports `<face> <action>` syntax; docs or blog posts written for Face-based subcommands applied to legacy apps; automation that always passes two arguments; Puppet version changes where a subcommand moved between legacy app and Face.

Related errors


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