puppetlabs/puppet · error · ArgumentError

Attempt to assign a value to unknown setting %{name}

Error message

Attempt to assign a value to unknown setting %{name}

What it means

Puppet::Settings::Values#set (the value bag bound to one config source: a section, CLI, or code) raises ArgumentError when asked to store a value for a name that has no registered default in @defaults — i.e. the setting was never declared via Puppet.settings.define_settings/newsetting. This guards programmatic assignment and config parsing from inventing settings.

Source

Thrown at lib/puppet/settings.rb:1566

  class Values
    extend Forwardable

    attr_reader :name

    def initialize(name, defaults)
      @name = name
      @values = {}
      @defaults = defaults
    end

    def_delegator :@values, :include?
    def_delegator :@values, :[], :lookup

    def set(name, value)
      default = @defaults[name]

      unless default
        raise ArgumentError, _("Attempt to assign a value to unknown setting %{name}") % { name: name.inspect }
      end

      # This little exception-handling dance ensures that a hook is
      # able to check whether a value for itself has been explicitly
      # set, while still preserving the existing value if the hook
      # throws (as was existing behavior)
      old_value = @values[name]
      @values[name] = value
      begin
        if default.has_hook?
          default.handle(value)
        end
      rescue Exception => e
        @values[name] = old_value
        raise e
      end
    end

View on GitHub (pinned to e227c27540)

Solutions

  1. Verify the name exists: Puppet.settings.setting(:name) (nil means unknown) or list them via Puppet.settings.all_settings.map(&:name) / `puppet config print`.
  2. Fix the name to the current Puppet version's spelling, or gate the assignment on the Puppet version.
  3. If the setting is genuinely new and custom, declare it first with Puppet.settings.define_settings(:section, :name => {...}).

Example fix

# before
Puppet.settings[:manifestdir] = '/etc/puppet/manifests'  # removed in newer Puppet

# after
if Puppet.settings.setting(:manifestdir)
  Puppet.settings[:manifestdir] = '/etc/puppet/manifests'
else
  Puppet.warning('manifestdir no longer exists in this Puppet version')
end
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, "#{name.inspect} is not a Puppet setting" if Puppet.settings.setting(name.to_sym).nil?
Puppet.settings[name] = value

Type guard

known_setting = ->(n) { !Puppet.settings.setting(n.to_sym).nil? }

Try / catch

begin
  Puppet.settings[name] = value
rescue ArgumentError => e
  raise unless e.message.include?('unknown setting')
  Puppet.err("#{e.message}; valid names via `puppet config print`")
  raise
end

Prevention

When it happens

Trigger: Calling Puppet.settings[:colour] = true (real name is `color`); assigning a setting that exists only in another Puppet version (e.g. manifestdir after Puppet 5 removed it); wrapper code or ERB-templated tooling setting keys by string interpolation with a typo; code that did not run its define_settings block before setting values.

Common situations: Upgrading/downgrading Puppet while in-house tooling still sets old names; typos in settings names in scripts; settings renamed between versions (color/colour-class mistakes); test harnesses that stub settings.

Related errors


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