{"record":{"id":"8a1b5804039c8553","repo":"puppetlabs/puppet","slug":"failed-to-convert-path-to-uri-detail","errorCode":null,"errorMessage":"Failed to convert '%{path}' to URI: %{detail}","messagePattern":"Failed to convert '%(.+?)' to URI: %(.+?)","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util.rb","lineNumber":308,"sourceCode":"      if unc\n        params[:host] = unc[1]\n        path = unc[2]\n      elsif path =~ %r{^[a-z]:/}i\n        path = '/' + path\n      end\n    end\n\n    # have to split *after* any relevant escaping\n    params[:path], params[:query] = uri_encode(path).split('?')\n    search_for_fragment = params[:query] ? :query : :path\n    if params[search_for_fragment].include?('#')\n      params[search_for_fragment], _, params[:fragment] = params[search_for_fragment].rpartition('#')\n    end\n\n    begin\n      URI::Generic.build(params)\n    rescue => detail\n      raise Puppet::Error, _(\"Failed to convert '%{path}' to URI: %{detail}\") % { path: path, detail: detail }, detail.backtrace\n    end\n  end\n  module_function :path_to_uri\n\n  # Get the path component of a URI\n  def uri_to_path(uri)\n    return unless uri.is_a?(URI)\n\n    # CGI.unescape doesn't handle space rules properly in uri paths\n    # URI.unescape does, but returns strings in their original encoding\n    path = uri_unescape(uri.path.encode(Encoding::UTF_8))\n\n    if Puppet::Util::Platform.windows? && uri.scheme == 'file'\n      if uri.host && !uri.host.empty?\n        path = \"//#{uri.host}\" + path # UNC\n      else\n        path.sub!(%r{^/}, '')\n      end","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util.rb#L290-L326","documentation":"Puppet::Util.path_to_uri converts a filesystem path into a file: URI: on Windows it rewrites backslashes and extracts a UNC host, then uri_encode escapes components, then splits on '?' and '#', and finally calls URI::Generic.build(params). Any exception from the build (typically URI::InvalidComponentError) is rescued and re-raised as Puppet::Error with the original path and detail (and backtrace) preserved. It is used by file resources' source handling and by metatype when recording resource locations.","triggerScenarios":"A path containing characters that uri_encode does not escape but URI::Generic.build rejects in a component (e.g. invalid host characters from a Windows UNC match, a malformed percent-escape, or reserved characters landing in the fragment/query split); calling Puppet::Util.path_to_uri directly with a malformed string; file sources with '#' or '?' mid-filename being split into fragment/query and reassembled invalidly.","commonSituations":"Files with '#', '?', or brackets in their names managed via a file source; Windows UNC paths with characters illegal in a URI host; deep integration code calling path_to_uri on user-supplied strings without sanitization.","solutions":["Rename the offending file/path to avoid URI-reserved characters (#, ?, [, backslash)","Escape the path before conversion: URI::DEFAULT_PARSER.escape(path) — or pass a cleaner source","If you control the Ruby call site, rescue Puppet::Error and inspect e.cause/original detail to find the bad component"],"exampleFix":"# before\nuri = Puppet::Util.path_to_uri('/srv/files/report#2?v=3.pdf')\n\n# after\nuri = Puppet::Util.path_to_uri('/srv/files/report_2_v3.pdf')","handlingStrategy":"try-catch","validationCode":"begin\n  URI::Generic.build(scheme: 'file', path: URI::DEFAULT_PARSER.escape(path))\nrescue URI::Error\n  puts 'not convertible; sanitize the path first'\nend","typeGuard":null,"tryCatchPattern":"begin\n  uri = Puppet::Util.path_to_uri(path)\nrescue Puppet::Error => e\n  # e.message contains the original detail; fall back to raw path handling\n  warn \"path not URI-convertible: #{e.message}\"\n  uri = nil\nend","preventionTips":["Avoid '#', '?', '[', ']' and backslashes in managed file names","Sanitize user-supplied paths (escape reserved characters) before conversion","On Windows UNC paths, keep the host component free of characters illegal in URI hosts"],"tags":["puppet","uri","file-resource","windows-paths"],"backgroundTag":"uri-construction-failure","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}