puppetlabs/puppet · error · Puppet::Pops::Types::StringConverter::FormatError

Illegal format '#{actual}' specified for value of Boolean ty

Error message

Illegal format '#{actual}' specified for value of Boolean type - expected one of the characters 'tTyYdxXobBeEfgGaAsp'

What it means

StringConverter raises this FormatError when formatting a Boolean with a format letter outside 'tTyYdxXobBeEfgGaAsp'. Booleans support true/false rendering (t), yes/no-ish forms (T), numeric conversion (dxXobBeEfgGaA — the value becomes 1.0/0.0 and is reformatted), and s/p for string/inspect forms. The else at string_converter.rb:709 fires for any other letter, e.g. '%q' or '%v'.

Source

Thrown at lib/puppet/pops/types/string_converter.rb:709

      # Boolean in numeric form, formated by integer rule
      numeric_bool = val ? 1 : 0
      string_formats = { Puppet::Pops::Types::PIntegerType::DEFAULT => f }
      _convert(TypeCalculator.infer_set(numeric_bool), numeric_bool, string_formats, indentation)

    when :e, :E, :f, :g, :G, :a, :A
      # Boolean in numeric form, formated by float rule
      numeric_bool = val ? 1.0 : 0.0
      string_formats = { Puppet::Pops::Types::PFloatType::DEFAULT => f }
      _convert(TypeCalculator.infer_set(numeric_bool), numeric_bool, string_formats, indentation)

    when :s
      apply_string_flags(f, val.to_s)

    when :p
      apply_string_flags(f, val.inspect)

    else
      raise FormatError.new('Boolean', f.format, 'tTyYdxXobBeEfgGaAsp')
    end
  end

  # Performs post-processing of literals to apply width and precision flags
  def apply_string_flags(f, literal_str)
    if f.left || f.width || f.prec
      fmt = '%'.dup
      fmt << '-' if f.left
      fmt << f.width.to_s if f.width
      fmt << '.' << f.prec.to_s if f.prec
      fmt << 's'
      Kernel.format(fmt, literal_str)
    else
      literal_str
    end
  end
  private :apply_string_flags

View on GitHub (pinned to e227c27540)

Solutions

  1. Use '%t'/'%T' for true/false or yes/no style output, '%s' for plain string form
  2. Branch on datatype before formatting mixed collections (case $v { Boolean: ..., default: ... })
  3. Whitelist the format letter against %w[t T y Y d x X o b B e E f g G a A s p]

Example fix

# before
$str = String($enabled, '%q')
# after
$str = String($enabled, '%t')
Defensive patterns

Strategy: validation

Validate before calling

fmt = '%q'
letter = fmt[/\A%[#\-+ 0\d.]*([a-zA-Z])\z/, 1]
raise ArgumentError, "#{fmt} invalid for Boolean" unless %w[t T y Y d x X o b B e E f g G a A s p].include?(letter)

Prevention

When it happens

Trigger: `String(true, '%q')`, `String($flag, '%v')`, `String(false, '%c')` — any conversion letter not in the allowed set applied to a Puppet Boolean. Often hit when a generic formatter applies one format string to a mixed hash of booleans, strings and numbers.

Common situations: Templating/report code that walks option hashes and applies a per-structure format; migrating Ruby `sprintf('%d', bool)` habits — %d actually works here, but %q (Ruby inspect idiom) does not.

Related errors


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