{"record":{"id":"039830c13b5b5327","repo":"puppetlabs/puppet","slug":"failed-to-call-getlongpathname","errorCode":null,"errorMessage":"Failed to call GetLongPathName","messagePattern":"Failed to call GetLongPathName","errorType":"exception","errorClass":"Puppet::Util::Windows::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/file.rb","lineNumber":257,"sourceCode":"\n  def readlink(link_name)\n    link = nil\n    open_symlink(link_name) do |handle|\n      link = resolve_symlink(handle)\n    end\n\n    link\n  end\n  module_function :readlink\n\n  def get_long_pathname(path)\n    converted = ''.dup\n    FFI::Pointer.from_string_to_wide_string(path) do |path_ptr|\n      # includes terminating NULL\n      buffer_size = GetLongPathNameW(path_ptr, FFI::Pointer::NULL, 0)\n      FFI::MemoryPointer.new(:wchar, buffer_size) do |converted_ptr|\n        if GetLongPathNameW(path_ptr, converted_ptr, buffer_size) == FFI::WIN32_FALSE\n          raise Puppet::Util::Windows::Error, _(\"Failed to call GetLongPathName\")\n        end\n\n        converted = converted_ptr.read_wide_string(buffer_size - 1)\n      end\n    end\n\n    converted\n  end\n  module_function :get_long_pathname\n\n  def get_short_pathname(path)\n    converted = ''.dup\n    FFI::Pointer.from_string_to_wide_string(path) do |path_ptr|\n      # includes terminating NULL\n      buffer_size = GetShortPathNameW(path_ptr, FFI::Pointer::NULL, 0)\n      FFI::MemoryPointer.new(:wchar, buffer_size) do |converted_ptr|\n        if GetShortPathNameW(path_ptr, converted_ptr, buffer_size) == FFI::WIN32_FALSE\n          raise Puppet::Util::Windows::Error, \"Failed to call GetShortPathName\"","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/file.rb#L239-L275","documentation":"Puppet::Util::Windows::File.get_long_pathname expands a path to its long form via GetLongPathNameW: a first call sizes the buffer, a second converts, and failure of the second call raises Puppet::Util::Windows::Error. GetLongPathNameW only succeeds when every component of the path actually exists - a nonexistent path is the leading cause (code 2/3), with access-denied on intermediate directories next.","triggerScenarios":"get_long_pathname(path) where path (or any parent) does not currently exist; the path is a network share whose server is unreachable; a parent directory denies traversal (5); the path is already long-form but contains wildcard/invalid characters.","commonSituations":"Expanding 8.3 short names (e.g. PROGRA~1, from legacy installers or ENV['TEMP']) for directories created later in the run; converting paths captured before a package uninstall removed them; concurrent deletion racing the conversion.","solutions":["Verify File.exist?(path) before converting - GetLongPathName requires an existing path","Map e.code: 2/3 missing component, 5 traversal denied, 53/1231 network share unreachable","Create the target directory tree first, then convert","Fall back to the original string when expansion is only cosmetic"],"exampleFix":"// before\nlong = Puppet::Util::Windows::File.get_long_pathname(short_path)  # raises if missing\n\n// after\nlong = if File.exist?(short_path)\n         Puppet::Util::Windows::File.get_long_pathname(short_path)\n       else\n         short_path\n       end","handlingStrategy":"validation","validationCode":"raise ArgumentError, \"#{path} must exist for long-path conversion\" unless File.exist?(path)\nlong = Puppet::Util::Windows::File.get_long_pathname(path)","typeGuard":null,"tryCatchPattern":"begin\n  long = Puppet::Util::Windows::File.get_long_pathname(path)\nrescue Puppet::Util::Windows::Error => e\n  raise if e.code == 5  # access denied is a real problem\n  long = path           # 2/3: component missing - keep original\nend","preventionTips":["Create the directory tree before expanding short names captured from ENV","Re-check existence right before converting - paths disappear mid-run","Treat long-path expansion as best-effort; keep the input as fallback"],"tags":["windows","file-system","path-conversion","win32-api","ffi","puppet"],"backgroundTag":"win32-path-conversion-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}