{"record":{"id":"4536d8a8f16c1ae8","repo":"puppetlabs/puppet","slug":"face-has-no-action-action-see-puppet-he","errorCode":null,"errorMessage":"'%{face}' has no %{action} action.  See `puppet help %{face}`.","messagePattern":"'%(.+?)' has no %(.+?) action\\.  See `puppet help %(.+?)`\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/puppet/application/face_base.rb","lineNumber":139,"sourceCode":"\n    if @action.nil?\n      @action = @face.get_default_action()\n      if @action\n        @is_default_action = true\n      else\n        # First try to handle global command line options\n        # But ignoring invalid options as this is a invalid action, and\n        # we want the error message for that instead.\n        begin\n          super\n        rescue OptionParser::InvalidOption\n        end\n\n        face   = @face.name\n        action = action_name.nil? ? 'default' : \"'#{action_name}'\"\n        msg = _(\"'%{face}' has no %{action} action.  See `puppet help %{face}`.\") % { face: face, action: action }\n\n        Puppet.err(msg)\n        Puppet::Util::Log.force_flushqueue()\n\n        exit false\n      end\n    end\n\n    # Now we can interact with the default option code to build behaviour\n    # around the full set of options we now know we support.\n    @action.options.each do |o|\n      o = @action.get_option(o) # make it the object.\n      self.class.option(*o.optparse) # ...and make the CLI parse it.\n    end\n\n    # ...and invoke our parent to parse all the command line options.\n    super\n  end\n\n  def find_global_settings_argument(item)","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/application/face_base.rb#L121-L157","documentation":"Emitted by Puppet::Application::FaceBase (face_base.rb:139) when the invoked face has no action with the requested name, or no default action when none is given (action renders as 'default'). The runner prints the message, flushes the log queue, and exits with failure status. It is CLI argument validation, not an exception callers can rescue.","triggerScenarios":"Running `puppet <face> <bogus-action>` — a typo, a removed action, or the wrong subcommand — e.g. `puppet module instal puppetlabs-apt`. Also hitting it programmatically by calling a face whose current version does not define the requested action symbol.","commonSituations":"Command-line typos; scripts written for a different Puppet version where an action was renamed or removed; custom faces not installed or plugin-synced to the node; tab-completion mistakes in runbooks.","solutions":["Run `puppet help <face>` (e.g. `puppet help module`) and use an action from that list","Fix the typo and rerun the command","Compare `puppet --version` across machines and align versions if the action is missing in the older one","For custom faces, verify the plugin is installed and discoverable before invoking it"],"exampleFix":"# before\n$ puppet module instal puppetlabs-apt\nError: 'module' has no 'instal' action.  See `puppet help module`.\n\n# after\n$ puppet module install puppetlabs-apt","handlingStrategy":"validation","validationCode":"require 'puppet/face'\n\nface = Puppet::Face[:module, :current]\naction = ARGV[0]\nunless face.actions.map(&:to_s).include?(action)\n  abort \"unknown action '#{action}'; valid actions: #{face.actions.join(', ')}\"\nend","typeGuard":"def known_action?(face, name)\n  !face.get_action(name.to_sym).nil?\nend","tryCatchPattern":null,"preventionTips":["Pin wrapper scripts to a tested Puppet version and exercise them in CI","Generate CLI usage from `puppet help <face>` in docs instead of hand-writing action names","Fail fast on unknown subcommands before doing side-effectful work"],"tags":["ruby","puppet","cli","face","action","command-line"],"backgroundTag":"unknown-cli-action","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}