puppetlabs/puppet · error · ArgumentError

purge_ssh_keys must be true, false, or an array of file name

Error message

purge_ssh_keys must be true, false, or an array of file names, not %{value}

What it means

Raised by the validate block of the `purge_ssh_keys` property on the `user` type when the value is neither a true/false form (symbol, boolean, or their strings, accepted via newvalues(:true, :false) and the intern check), nor a String (treated as one path), nor an Array of path strings. Any other type — Hash, Integer, Symbol like :yes — fails through to this ArgumentError with value.inspect embedded.

Source

Thrown at lib/puppet/type/user.rb:750

      # Use Symbols instead of booleans until PUP-1967 is resolved.
      newvalues(:true, :false)

      validate do |value|
        if [:true, :false].include? value.to_s.intern
          return
        end

        value = [value] if value.is_a?(String)
        if value.is_a?(Array)
          value.each do |entry|
            raise ArgumentError, _("Each entry for purge_ssh_keys must be a string, not a %{klass}") % { klass: entry.class } unless entry.is_a?(String)

            valid_home = Puppet::Util.absolute_path?(entry) || entry =~ %r{^~/|^%h/}
            raise ArgumentError, _("Paths to keyfiles must be absolute, not %{entry}") % { entry: entry } unless valid_home
          end
          return
        end
        raise ArgumentError, _("purge_ssh_keys must be true, false, or an array of file names, not %{value}") % { value: value.inspect }
      end

      munge do |value|
        # Resolve string, boolean and symbol forms of true and false to a
        # single representation.
        case value
        when :false, false, "false"
          []
        when :true, true, "true"
          home = homedir
          home ? ["#{home}/.ssh/authorized_keys"] : []
        else
          # value can be a string or array - munge each value
          [value].flatten.filter_map do |entry|
            authorized_keys_path(entry)
          end
        end
      end

View on GitHub (pinned to e227c27540)

Solutions

  1. Use a real boolean: `purge_ssh_keys => true` (purges keys in the user's ~/.ssh) or `=> false`
  2. Or an array of absolute/home-relative path strings
  3. Normalize truthy strings in the profile to a Boolean before passing

Example fix

# before
user { 'alice':
  ensure          => present,
  purge_ssh_keys  => 'yes',
}

# after
user { 'alice':
  ensure          => present,
  purge_ssh_keys  => true,
}
Defensive patterns

Strategy: validation

Validate before calling

# Normalize arbitrary truthy input to the three accepted shapes
v = 'true' if v.to_s.downcase == 'yes'
ok = [true, false, 'true', 'false', :true, :false].include?(v) || (v.is_a?(Array) && v.all? { |e| e.is_a?(String) }) || v.is_a?(String)
raise ArgumentError, "purge_ssh_keys must be true/false or an array of paths, got #{v.inspect}" unless ok

Type guard

def purge_ssh_keys_value?(v)
  [TrueClass, FalseClass, String].any? { |c| v.is_a?(c) } || (v.is_a?(Array) && v.all? { |e| e.is_a?(String) })
end

Prevention

When it happens

Trigger: `purge_ssh_keys => 'yes'` (String, but fails the absolute-path companion check), `=> :yes`, `=> {'keys' => [...]}`, `=> 1`; JSON data where true arrives as the string 'TRUE' is fine, but arbitrary strings fall through to path validation.

Common situations: Hiera/JSON truthy variants ('yes'/'no' are NOT recognized — only 'true'/'false'); passing a hash of user→keys by mistake; ENC tools emitting symbols.

Related errors


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