{"record":{"id":"6ec888d2bf9d5193","repo":"puppetlabs/puppet","slug":"after-action-takes-three-arguments-action-args","errorCode":null,"errorMessage":"after_action takes three arguments, action, args, and options","messagePattern":"after_action takes three arguments, action, args, and options","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/interface/option_builder.rb","lineNumber":76,"sourceCode":"    @option.before_action = block\n  end\n\n  # Sets a block to be executed after an action is invoked.\n  # !(see before_action)\n  # @api public\n  # @dsl Faces\n  def after_action(&block)\n    unless block\n      # TRANSLATORS 'after_action' is a method name and should not be translated\n      raise ArgumentError, _(\"%{option} after_action requires a block\") % { option: @option }\n    end\n    if @option.after_action\n      # TRANSLATORS 'after_action' is a method name and should not be translated\n      raise ArgumentError, _(\"%{option} already has an after_action set\") % { option: @option }\n    end\n    unless block.arity == 3 then\n      # TRANSLATORS 'after_action' is a method name and should not be translated\n      raise ArgumentError, _(\"after_action takes three arguments, action, args, and options\")\n    end\n\n    @option.after_action = block\n  end\n\n  # Sets whether the option is required. If no argument is given it\n  # defaults to setting it as a required option.\n  # @api public\n  # @dsl Faces\n  def required(value = true)\n    @option.required = value\n  end\n\n  # Sets a block that will be used to compute the default value for this\n  # option. It will be evaluated when the action is invoked. The block\n  # should take no arguments.\n  # @api public\n  # @dsl Faces","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/interface/option_builder.rb#L58-L94","documentation":"OptionBuilder#after_action enforces `block.arity == 3` because it calls the hook with (action, args, options) (lib/puppet/interface/option_builder.rb:76). Any other declared arity — fewer parameters, splats, or inexact procs — fails the strict equality check at face load.","triggerScenarios":"`after_action { |action, args| ... }` (arity 2); `after_action { |*a| ... }` (arity -1).","commonSituations":"Trimming parameters after refactoring; splat-style hook blocks copied from logging helpers.","solutions":["Declare exactly three parameters: `after_action { |action, args, options| ... }`","Underscore the ones you ignore: `|_action, _args, options|`","Check `hook.arity == 3` before registering hooks held in variables"],"exampleFix":"# before\nafter_action { |action, options| log(action) }\n\n# after\nafter_action { |action, args, options| log(action) }","handlingStrategy":"validation","validationCode":"hook = proc { |action, args, options| log(action) }\nraise ArgumentError, 'after_action hook must take exactly 3 args' unless hook.arity == 3\nafter_action(&hook)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the exact `|action, args, options|` signature for after_action too","No splat hooks — arity must equal 3","Assert arity when hooks are stored in variables or config"],"tags":["puppet","faces","dsl","arity","argumenterror"],"backgroundTag":"block-arity-mismatch","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}