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

Illegal format '#{actual}' specified for value of String typ

Error message

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

What it means

StringConverter raises this FormatError when formatting a String with a conversion letter outside 'cCudspt': 'c'/'C' (camel/upcase first letter... upcased copy), 'u' (uppercase), 'd' (downcase), 's' (as-is), 'p' (Puppet-quoted), 't' (strip whitespace). The else at string_converter.rb:849 raises FormatError('String', f.format, 'cCudspt'). Numeric letters that work for Integer/Float are illegal for String values.

Source

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

    when :C
      c_val = val.split('::').map(&:capitalize).join('::')
      f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.tr('C', 's'), c_val)

    when :u
      c_val = val.upcase
      f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.tr('u', 's'), c_val)

    when :d
      c_val = val.downcase
      f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.tr('d', 's'), c_val)

    when :t # trim
      c_val = val.strip
      f.alt? ? apply_string_flags(f, puppet_quote(c_val)) : Kernel.format(f.orig_fmt.tr('t', 's'), c_val)

    else
      raise FormatError.new('String', f.format, 'cCudspt')
    end
  end

  # Performs a '%p' formatting of the given _str_ such that the output conforms to Puppet syntax. An ascii string
  # without control characters, dollar, single-qoute, or backslash, will be quoted using single quotes. All other
  # strings will be quoted using double quotes.
  #
  # @param [String] str the string that should be formatted
  # @param [Boolean] enforce_double_quotes if true the result will be double quoted (even if single quotes would be possible)
  # @return [String] the formatted string
  #
  # @api public
  def puppet_quote(str, enforce_double_quotes = false)
    if enforce_double_quotes
      return puppet_double_quote(str)
    end

    # Assume that the string can be single quoted

View on GitHub (pinned to e227c27540)

Solutions

  1. Use '%s' (plain), '%d' (downcase), '%u' (uppercase), '%t' (strip) or '%p' (quoted) for strings
  2. Remember '%d' on a String means downcase — if you meant a number, convert first: String(Integer($s), '%d')
  3. Whitelist dynamic format letters against %w[c C u d s p t]

Example fix

# before
$str = String($label, '%q')
# after
$str = String($label, '%p')
Defensive patterns

Strategy: validation

Validate before calling

fmt = '%x'
letter = fmt[/\A%[#\-+ 0\d.]*([a-zA-Z])\z/, 1]
raise ArgumentError, "#{fmt} invalid for String" unless %w[c C u d s p t].include?(letter)

Prevention

When it happens

Trigger: `String('hi', '%x')`, `String($name, '%d' )` used intending 'downcase' — %d for a String is illegal (d means downcase only in the sense of the letter list... actually 'd' IS allowed and downcases); the real trigger is letters like '%q', '%v', '%e' applied to String values. Any conversion letter not in cCudspt against a String.

Common situations: Copy-pasting numeric formats onto label/name data; applying '%v' (n/a) formatting from Undef examples to strings; format strings sourced from Hiera meant for a different field type.

Related errors


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