puppetlabs/puppet · error · Puppet::Pops::Types::StringConverter::FormatError
Illegal format '#{actual}' specified for value of Float type
Error message
Illegal format '#{actual}' specified for value of Float type - expected one of the characters 'dxXobBeEfgGaAsp' What it means
StringConverter raises this FormatError when formatting a Float with a conversion letter outside 'dxXobBeEfgGaAsp'. Floats accept integer-conversion letters (dxXobB — the value is truncated with val.to_i first), float letters (eEfgGaA), '%p' (Ruby inspect form) and '%s' (quoted inspect form with alt flag). Notably '%c' (character) — valid for Integer — is illegal here; the else at string_converter.rb:768 raises FormatError('Float', f.format, 'dxXobBeEfgGaAsp').
Source
Thrown at lib/puppet/pops/types/string_converter.rb:768
end
end
# @api private
def string_PFloatType(val_type, val, format_map, _)
f = get_format(val_type, format_map)
case f.format
when :d, :x, :X, :o, :b, :B
Kernel.format(f.orig_fmt, val.to_i)
when :e, :E, :f, :g, :G, :a, :A, :p
Kernel.format(f.orig_fmt, val)
when :s
float_str = f.alt? ? "\"#{Kernel.format('%p', val)}\"" : Kernel.format('%p', val)
Kernel.format(f.orig_fmt, float_str)
else
raise FormatError.new('Float', f.format, 'dxXobBeEfgGaAsp')
end
end
# @api private
def string_PBinaryType(val_type, val, format_map, _)
f = get_format(val_type, format_map)
substitute = f.alt? ? 'p' : 's'
case f.format
when :s
val_to_convert = val.binary_buffer
if !f.alt?
# Assume it is valid UTF-8
val_to_convert = val_to_convert.dup.force_encoding('UTF-8')
# If it isn't
unless val_to_convert.valid_encoding?
# try to convert and fail with details about what is wrong
val_to_convert = val.binary_buffer.encode('UTF-8')
endView on GitHub (pinned to e227c27540)
Solutions
- Use '%f', '%e', '%g' (float forms), '%d' (truncates via to_i) or '%s' for floats
- Convert to Integer first if you truly want character output: String(1.5.to_i, '%c')
- Whitelist dynamic format letters against %w[d x X o b B e E f g G a A s p]
Example fix
# before $str = String($ratio, '%c') # after $str = String($ratio, '%f')
Defensive patterns
Strategy: validation
Validate before calling
fmt = '%c'
letter = fmt[/\A%[#\-+ 0\d.]*([a-zA-Z])\z/, 1]
raise ArgumentError, "#{fmt} invalid for Float" unless %w[d x X o b B e E f g G a A s p].include?(letter) Prevention
- Use %f/%e/%g for floats; convert with .to_i first if integer semantics are wanted
- Do not reuse Integer format lists verbatim for Floats (%c is Integer-only)
- Whitelist dynamic format letters per numeric type
When it happens
Trigger: `String(1.5, '%c')`, `String($ratio, '%v')`, `String(3.14, '%q')` — any letter not in dxXobBeEfgGaAsp applied to a Float value in DSL `String()` calls or Ruby StringConverter invocations.
Common situations: Reusing an Integer format list for floats and assuming %c carries over; applying per-collection formats to mixed numeric data; porting C printf specs that use %c for ordinals.
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 Undef type
- Illegal format '#{actual}' specified for value of Boolean ty
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/b5697f5eec9fc95f.
Report an issue: GitHub.