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

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

Error message

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

What it means

StringConverter (Puppet::Pops::Types::StringConverter) raises FormatError — an ArgumentError subclass — when `String(value, format)` is asked to render an Object type value with a format character outside the allowed set. For PObjectType values only 's' (to_s), 'p' (TypeFormatter, Puppet-notation) and 'q' (inspect) are legal; any other char falls into the else branch at string_converter.rb:585 and raises with the type name 'Object' and the valid set 'spq'. This is the object-type member of Puppet's per-type printf-style format validation family.

Source

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

    result.container_string_formats = validate_input(fmt['string_formats'])
    result
  end
  private :validate_container_input

  def string_PObjectType(val_type, val, format_map, indentation)
    f = get_format(val_type, format_map)
    case f.format
    when :p
      fmt = TypeFormatter.singleton
      indentation = indentation.indenting(f.alt? || indentation.is_indenting?)
      fmt = fmt.indented(indentation.level, 2) if indentation.is_indenting?
      fmt.string(val)
    when :s
      val.to_s
    when :q
      val.inspect
    else
      raise FormatError.new('Object', f.format, 'spq')
    end
  end

  def string_PObjectTypeExtension(val_type, val, format_map, indentation)
    string_PObjectType(val_type.base_type, val, format_map, indentation)
  end

  def string_PRuntimeType(val_type, val, format_map, indent)
    # Before giving up on this, and use a string representation of the unknown
    # object, a check is made to see if the object can present itself as
    # a hash or an array. If it can, then that representation is used instead.
    case val
    when Hash
      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

View on GitHub (pinned to e227c27540)

Solutions

  1. Use '%p' (Puppet notation via TypeFormatter) or '%s' (plain to_s) for Object values
  2. Format a specific attribute instead of the whole object: String($obj.field, '%d')
  3. If the format arrives from data, validate its conversion letter against %w[s p q] before use

Example fix

# before
$str = String($my_object, '%d')
# after
$str = String($my_object, '%p')
Defensive patterns

Strategy: validation

Validate before calling

# Validate the conversion letter before formatting an Object value
fmt = '%d'
letter = fmt[/\A%[#\-+ 0\d.]*([a-zA-Z])\z/, 1]
raise ArgumentError, "#{fmt} invalid for Object" unless %w[s p q].include?(letter)

Prevention

When it happens

Trigger: In Puppet DSL: `String($my_object, '%d')` or any format string whose conversion letter is not s/p/q applied to a Puppet Object value. In Ruby: StringConverter.convert inferred a PObjectType for the value and the format map (e.g. from puppetlabs-stdlib or custom function options) contains an invalid char.

Common situations: Reusing a printf format meant for scalars against an object attribute; copy-pasting `'%v'` or `'%d'` formats from Integer/String examples; passing user-supplied format strings from Hiera into a function that formats an Object.

Related errors


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