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

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

Error message

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

What it means

Raised by StringConverter when formatting a Runtime type value (PRuntimeType — a Ruby object surfaced into the Puppet type system, e.g. Runtime['ruby', 'MyClass']) with a format character other than 's' (to_s), 'p' (puppet-quoted string) or 'q' (inspect). The else branch at string_converter.rb:617 raises FormatError('Runtime', f.format, 'spq'). Note the method first tries to coerce arrays/hashes into Puppet containers; the error only fires when the value stays an opaque runtime object.

Source

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

      hash = val.to_hash
      # Ensure that the returned value isn't derived from Hash
      return string_PHashType(val_type, hash, format_map, indent) if hash.instance_of?(Hash)
    when Array
      array = val.to_a
      # Ensure that the returned value isn't derived from Array
      return string_PArrayType(val_type, array, format_map, indent) if array.instance_of?(Array)
    end

    f = get_format(val_type, format_map)
    case f.format
    when :s
      val.to_s
    when :p
      puppet_quote(val.to_s)
    when :q
      val.inspect
    else
      raise FormatError.new('Runtime', f.format, 'spq')
    end
  end

  # Basically string_PAnyType converts the value to a String and then formats it according
  # to the resulting type
  #
  # @api private
  def string_PAnyType(val_type, val, format_map, _)
    f = get_format(val_type, format_map)
    Kernel.format(f.orig_fmt, val)
  end

  def string_PDefaultType(val_type, val, format_map, _)
    f = get_format(val_type, format_map)
    apply_string_flags(f, case f.format
                          when :d, :s, :p
                            f.alt? ? '"default"' : 'default'
                          when :D

View on GitHub (pinned to e227c27540)

Solutions

  1. Use '%s', '%p' or '%q' for Runtime-typed values
  2. Convert the object to a Puppet-native value first (to_s/to_hash/to_a) and format that
  3. Validate the format letter against %w[s p q] when formats come from data

Example fix

# before
$str = String($ruby_obj, '%d')
# after
$str = String($ruby_obj, '%s')
Defensive patterns

Strategy: validation

Validate before calling

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

Prevention

When it happens

Trigger: `String($ruby_obj, '%d')` where $ruby_obj has inferred type Runtime['ruby', ...]; custom Puppet functions in Ruby returning arbitrary objects that later flow into String(..., fmt) with a numeric/other format letter; format maps built for other types reused against runtime values.

Common situations: Mixing printf habits from C/Ruby into Puppet String() calls; formatting values returned by Ruby API extensions whose type cannot be mapped to a Puppet type; debugging output code that applies one hardcoded format to heterogeneous values.

Related errors


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