{"record":{"id":"04fea4d4ff8a4a97","repo":"puppetlabs/puppet","slug":"getfileattributes-file-name","errorCode":null,"errorMessage":"GetFileAttributes(#{file_name})","messagePattern":"GetFileAttributes\\(#(.+?)\\)","errorType":"exception","errorClass":"Puppet::Util::Windows::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/file.rb","lineNumber":93,"sourceCode":"      reparse_point = (result & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT\n      if reparse_point && symlink_reparse_point?(path)\n        # walk the symlink and try again...\n        seen_paths << path.downcase\n        path = readlink(path)\n      else\n        # file was found and its not a symlink\n        return true\n      end\n    end\n\n    false\n  end\n  module_function :exist?\n\n  def get_attributes(file_name, raise_on_invalid = true)\n    result = GetFileAttributesW(wide_string(file_name.to_s))\n    if raise_on_invalid && result == INVALID_FILE_ATTRIBUTES\n      raise Puppet::Util::Windows::Error, \"GetFileAttributes(#{file_name})\"\n    end\n\n    result\n  end\n  module_function :get_attributes\n\n  def add_attributes(path, flags)\n    oldattrs = get_attributes(path)\n\n    if (oldattrs | flags) != oldattrs\n      set_attributes(path, oldattrs | flags)\n    end\n  end\n  module_function :add_attributes\n\n  def remove_attributes(path, flags)\n    oldattrs = get_attributes(path)\n","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/file.rb#L75-L111","documentation":"Puppet::Util::Windows::File.get_attributes queries GetFileAttributesW and raises Puppet::Util::Windows::Error when the API returns INVALID_FILE_ATTRIBUTES (0xFFFFFFFF). That sentinel means the path could not be queried - typically nonexistent path or access denied on some parent - so e.code is the discriminator. The method has an escape hatch: pass raise_on_invalid=false to get the raw sentinel back instead of an exception.","triggerScenarios":"get_attributes(path) with the default raise_on_invalid=true on a path that does not exist (2/3), a path whose parent directory denies traversal (5), a malformed UNC (\\\\server\\share\\...) or drive letter, or a file being deleted concurrently between an existence check and the query.","commonSituations":"Probing for files under locked-down directories (e.g. other users' profiles) where even attribute queries are denied; race with uninstallers deleting files mid-run; typos in configured paths; tools that assume error == not-found and mask access-denied as missing.","solutions":["Verify the path spelling/existence first (File.exist?) when a miss is expected","Pass raise_on_invalid: false and compare the result to INVALID_FILE_ATTRIBUTES yourself","Inspect e.code: 5 means access denied (fix ACLs/elevation), 2/3 means missing (fix the path)","For repeated probes on protected trees, run elevated or relax the parent-folder ACL"],"exampleFix":"// before\nattrs = Puppet::Util::Windows::File.get_attributes(path)  # raises if missing\n\n// after\nattrs = Puppet::Util::Windows::File.get_attributes(path, false)\nmissing = attrs == Puppet::Util::Windows::File::INVALID_FILE_ATTRIBUTES","handlingStrategy":"fallback","validationCode":"attrs = Puppet::Util::Windows::File.get_attributes(path, false)\nif attrs == Puppet::Util::Windows::File::INVALID_FILE_ATTRIBUTES\n  # missing OR access-denied - distinguish before deciding\n  Puppet.debug(\"cannot query attributes for #{path}\")\nend","typeGuard":null,"tryCatchPattern":"begin\n  attrs = Puppet::Util::Windows::File.get_attributes(path)\nrescue Puppet::Util::Windows::Error => e\n  raise unless [2, 3, 5].include?(e.code)\n  attrs = nil  # treat as absent/inaccessible\nend","preventionTips":["Pass raise_on_invalid: false when probing - it is the documented escape hatch","Remember INVALID_FILE_ATTRIBUTES conflates 'missing' with 'access denied'","Validate UNC and drive-letter spellings before querying system paths"],"tags":["windows","file-system","win32-api","ffi","file-attributes","puppet"],"backgroundTag":"win32-file-attributes-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}