{"record":{"id":"825e4ca8a826b66f","repo":"puppetlabs/puppet","slug":"illegal-format-actual-specified-for-value-of-825e4c","errorCode":null,"errorMessage":"Illegal format '#{actual}' specified for value of URI type - expected one of the characters 'sp'","messagePattern":"Illegal format '#(.+?)' specified for value of URI type - expected one of the characters 'sp'","errorType":"validation","errorClass":"Puppet::Pops::Types::StringConverter::FormatError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pops/types/string_converter.rb","lineNumber":1130,"sourceCode":"    else\n      raise FormatError.new('Type', f.format, 'sp')\n    end\n  end\n\n  # @api private\n  def string_PURIType(val_type, val, format_map, indentation)\n    f = get_format(val_type, format_map)\n    case f.format\n    when :p\n      fmt = TypeFormatter.singleton\n      indentation = indentation.indenting(f.alt? || indentation.is_indenting?)\n      fmt = fmt.indented(indentation.level, 2) if indentation.is_indenting?\n      fmt.string(val)\n    when :s\n      str_val = val.to_s\n      Kernel.format(f.orig_fmt, f.alt? ? puppet_quote(str_val) : str_val)\n    else\n      raise FormatError.new('URI', f.format, 'sp')\n    end\n  end\n\n  # Maps the inferred type of o to a formatting rule\n  def get_format(val_t, format_options)\n    fmt = format_options.find { |k, _| k.assignable?(val_t) }\n    return fmt[1] unless fmt.nil?\n\n    Format.new(\"%s\")\n  end\n  private :get_format\nend\nend\nend\n","sourceCodeStart":1112,"sourceCodeEnd":1145,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pops/types/string_converter.rb#L1112-L1145","documentation":"StringConverter raises this FormatError when formatting a Puppet URI value (PURIType, created by URI('...')) with a conversion letter other than 's' (plain to_s, Puppet-quoted with alt flag) or 'p' (TypeFormatter rendering, indentation-aware). The else at string_converter.rb:1130 raises FormatError('URI', f.format, 'sp'). This is the last member of the per-type format validation chain in string_converter.rb.","triggerScenarios":"`String(URI('https://x'), '%d')` or any non-s/p letter applied to a URI value; typically when URLs stored as URI-typed data are fed to a shared formatting helper with a scalar format.","commonSituations":"Formatting endpoint lists from Hiera that were parsed with URI(); report generation applying uniform formats to mixed data; migration from String-typed URLs to URI() validation which changes the inferred type and thus the legal format set.","solutions":["Use '%s' for the plain URL string or '%p' for Puppet notation","If only string handling is needed, convert: String(String($url), $fmt) or keep URLs as plain Strings","Whitelist dynamic format letters against %w[s p]"],"exampleFix":"# before\n$str = String($url, '%d')\n# after\n$str = String($url, '%s')","handlingStrategy":"validation","validationCode":"fmt = '%d'\nletter = fmt[/\\A%[#\\-+ 0\\d.]*([a-zA-Z])\\z/, 1]\nraise ArgumentError, \"#{fmt} invalid for URI values\" unless %w[s p].include?(letter)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only %s and %p are valid for URI values","If URLs never need type-aware formatting, keep them as plain Strings instead of URI()","Watch inferred-type changes when upgrading validation from String to URI"],"tags":["puppet","pops","string-conversion","format-error","uri"],"backgroundTag":"invalid-format-specifier","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}