puppetlabs/puppet · error · ArgumentError
%{option} already has a default value
Error message
%{option} already has a default value What it means
OptionBuilder#default_to raises when `@option.has_default?` is already true — an option can carry only one default (lib/puppet/interface/option_builder.rb:101). Puppet does not chain or override defaults, so the second declaration is a definition error, not a replacement.
Source
Thrown at lib/puppet/interface/option_builder.rb:101
# defaults to setting it as a required option.
# @api public
# @dsl Faces
def required(value = true)
@option.required = value
end
# Sets a block that will be used to compute the default value for this
# option. It will be evaluated when the action is invoked. The block
# should take no arguments.
# @api public
# @dsl Faces
def default_to(&block)
unless block
# TRANSLATORS 'default_to' is a method name and should not be translated
raise ArgumentError, _("%{option} default_to requires a block") % { option: @option }
end
if @option.has_default?
raise ArgumentError, _("%{option} already has a default value") % { option: @option }
end
unless block.arity == 0
# TRANSLATORS 'default_to' is a method name and should not be translated
raise ArgumentError, _("%{option} default_to block should not take any arguments") % { option: @option }
end
@option.default = block
end
end
View on GitHub (pinned to e227c27540)
Solutions
- Keep a single `default_to` block and put the branching inside it: `default_to { env == :test ? 'dev' : 'production' }`
- Delete the stale default after consolidating
- Remember `required` + `default_to` is also rejected (see errors 280/282) — pick exactly one of required/default per option
Example fix
# before
option "--environment" do
default_to { "production" }
default_to { "development" }
end
# after
option "--environment" do
default_to { Puppet.settings[:environment] }
end Defensive patterns
Strategy: validation
Validate before calling
# on an Option object before setting a default
raise ArgumentError, 'default already set' if opt.has_default?
opt.default = -> { 'production' } Prevention
- Keep exactly one default per option; branch inside the block instead of redeclaring
- Grep option blocks for multiple `default_to` lines before committing
- Remember defaults are single-slot — there is no override or chain semantics
When it happens
Trigger: Two `default_to` blocks in one option block; a `default_to` call after the Option already got a default via `opt.default = proc`.
Common situations: Copy-pasted option blocks both carrying defaults; environment-specific tuning that appends a second default instead of editing the first.
Related errors
- %{option} already has a before_action set
- %{option} already has an after_action set
- %{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/48451b87b9e7d854.
Report an issue: GitHub.