puppetlabs/puppet · error · ArgumentError
%{option} after_action requires a block
Error message
%{option} after_action requires a block What it means
OptionBuilder#after_action, the post-invocation counterpart of before_action, equally requires a block literal (lib/puppet/interface/option_builder.rb:68). A bare `after_action` call inside an option block raises ArgumentError at face-load time with the option name interpolated. The hook runs after the action body completes.
Source
Thrown at lib/puppet/interface/option_builder.rb:68
# TRANSLATORS 'before_action' is a method name and should not be translated
raise ArgumentError, _("%{option} already has a before_action set") % { option: @option }
end
unless block.arity == 3 then
# TRANSLATORS 'before_action' is a method name and should not be translated
raise ArgumentError, _("before_action takes three arguments, action, args, and options")
end
@option.before_action = block
end
# Sets a block to be executed after an action is invoked.
# !(see before_action)
# @api public
# @dsl Faces
def after_action(&block)
unless block
# TRANSLATORS 'after_action' is a method name and should not be translated
raise ArgumentError, _("%{option} after_action requires a block") % { option: @option }
end
if @option.after_action
# TRANSLATORS 'after_action' is a method name and should not be translated
raise ArgumentError, _("%{option} already has an after_action set") % { option: @option }
end
unless block.arity == 3 then
# TRANSLATORS 'after_action' is a method name and should not be translated
raise ArgumentError, _("after_action takes three arguments, action, args, and options")
end
@option.after_action = block
end
# Sets whether the option is required. If no argument is given it
# defaults to setting it as a required option.
# @api public
# @dsl Faces
def required(value = true)View on GitHub (pinned to e227c27540)
Solutions
- Always pass a literal block: `after_action { |action, args, options| ... }`
- Wrap named methods: `after_action { |*a| cleanup(*a) }`
- Guard conditional registration: `after_action { ... } if cleanup_needed`
Example fix
# before
option "--verbose" do
after_action
end
# after
option "--verbose" do
after_action do |action, args, options|
log_completion(action, options)
end
end Defensive patterns
Strategy: validation
Validate before calling
# when the hook comes from a variable raise ArgumentError, 'after_action needs a block' if hook.nil? after_action(&hook) # inside the option block
Prevention
- Always write `after_action do |action, args, options| ... end` with a literal block
- Check hook variables for nil before passing with `&`
- Treat before_action and after_action symmetrically when refactoring
When it happens
Trigger: `option '--foo' do after_action end` (no block); `after_action(&hook)` where hook is nil.
Common situations: Symmetrical refactoring where before_action got a block but after_action was left as a placeholder; optional cleanup hooks that were never assigned.
Related errors
- %{option} before_action requires a block
- %{option} default_to requires a block
- %{name} can't be optional and have a default value
- default value for %{name} is a %{class_name}, not a proc
- before action hook for %{name} is a %{class_name}, not a pro
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/5abb447bcf936603.
Report an issue: GitHub.