puppetlabs/puppet · error · Puppet::Pops::Types::StringConverter::FormatError
Illegal format '#{actual}' specified for value of Undef type
Error message
Illegal format '#{actual}' specified for value of Undef type - expected one of the characters 'nudxXobBeEfgGaAvVsp' What it means
StringConverter raises this FormatError when formatting an Undef value (nil in Puppet, `undef` in DSL) with a format letter outside the wide set 'nudxXobBeEfgGaAvVsp'. Undef is special-cased to render as 'nil'/'null' (n), 'NaN' for numeric letters (dxXobBeEfgGaA), 'n/a'/'N/A' (v/V), ''/'""' (s) and 'undef'/'"undef"' (p); everything else hits the else at string_converter.rb:661. This is the most permissive member of the format family because undef can legitimately stand in for any scalar.
Source
Thrown at lib/puppet/pops/types/string_converter.rb:661
def string_PUndefType(val_type, val, format_map, _)
f = get_format(val_type, format_map)
apply_string_flags(f, case f.format
when :n
f.alt? ? 'null' : 'nil'
when :u
f.alt? ? 'undefined' : 'undef'
when :d, :x, :X, :o, :b, :B, :e, :E, :f, :g, :G, :a, :A
'NaN'
when :v
'n/a'
when :V
'N/A'
when :s
f.alt? ? '""' : ''
when :p
f.alt? ? '"undef"' : 'undef'
else
raise FormatError.new('Undef', f.format,
'nudxXobBeEfgGaAvVsp')
end)
end
# @api private
def string_PBooleanType(val_type, val, format_map, indentation)
f = get_format(val_type, format_map)
case f.format
when :t
# 'true'/'false' or 't'/'f' if in alt mode
str_bool = val.to_s
apply_string_flags(f, f.alt? ? str_bool[0] : str_bool)
when :T
# 'True'/'False' or 'T'/'F' if in alt mode
str_bool = val.to_s.capitalize
apply_string_flags(f, f.alt? ? str_bool[0] : str_bool)
View on GitHub (pinned to e227c27540)
Solutions
- Use '%s' (empty string / quoted with #) or '%n' ('nil') for undef
- Default the variable first: String($x | default { 'n/a' }, '%s') or `$x = pick($x, 'n/a')`
- Validate format letters against the allowed set when formats are dynamic
Example fix
# before $str = String($maybe_undef, '%t') # after $str = String($maybe_undef, '%s')
Defensive patterns
Strategy: validation
Validate before calling
fmt = '%t'
letter = fmt[/\A%[#\-+ 0\d.]*([a-zA-Z])\z/, 1]
raise ArgumentError, "#{fmt} invalid for undef" unless %w[n u d x X o b B e E f g G a A v V s p].include?(letter) Prevention
- Use pick() or an if/else to substitute a placeholder before formatting optional values
- Prefer %s or %n when a variable may be undef
- Test formatting helpers against undef and default inputs, not just populated values
When it happens
Trigger: `String(undef, '%t')`, `String(undef, '%c')`, `String(undef, '%h')` — any letter not in nudxXobBeEfgGaAvVsp; commonly a format like '%q' (legal for Object but not Undef) applied to an optional variable that is undef.
Common situations: Formatting optional data from Hiera where a lookup returns undef and the code applies a fixed format meant for present values; '%v' works for undef but '%t' or '%q' does not, surprising developers migrating between type-specific formats.
Related errors
- Illegal format '#{actual}' specified for value of Object typ
- Illegal format '#{actual}' specified for value of Runtime ty
- Illegal format '#{actual}' specified for value of Default ty
- Illegal format '#{actual}' specified for value of Boolean ty
- Illegal format '#{actual}' specified for value of Integer ty
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/6c4eb73146012f5c.
Report an issue: GitHub.