{"record":{"id":"1abd807dc4bc76bb","repo":"restic/restic","slug":"could-not-determine-file-attributes-s","errorCode":null,"errorMessage":"could not determine file attributes: %s","messagePattern":"could not determine file attributes: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/fs/stat_darwin.go","lineNumber":47,"sourceCode":"\t\tBlocks:    s.Blocks,\n\t\tSize:      s.Size,\n\n\t\tAccessTime: time.Unix(s.Atimespec.Unix()),\n\t\tModTime:    time.Unix(s.Mtimespec.Unix()),\n\t\tChangeTime: time.Unix(s.Ctimespec.Unix()),\n\n\t\tsys: s,\n\t}\n}\n\n// RecallOnDataAccess checks if a file is available locally on the disk or if the file is\n// just a dataless files which must be downloaded from a remote server. This is typically used\n// in cloud syncing services (e.g. iCloud drive) to prevent downloading files from cloud storage\n// until they are accessed.\nfunc (fi *ExtendedFileInfo) RecallOnDataAccess() (bool, error) {\n\textAttribute, ok := fi.sys.(*syscall.Stat_t)\n\tif !ok {\n\t\treturn false, fmt.Errorf(\"could not determine file attributes: %s\", fi.Name)\n\t}\n\tconst mask uint32 = unix.SF_DATALESS // 0x40000000\n\tif extAttribute.Flags&mask == mask {\n\t\treturn true, nil\n\t}\n\n\treturn false, nil\n}\n","sourceCodeStart":29,"sourceCodeEnd":56,"githubUrl":"https://github.com/restic/restic/blob/a80be1478a4c537f8396e0db2b05120aa78f11e0/internal/fs/stat_darwin.go#L29-L56","documentation":"On macOS, ExtendedFileInfo.RecallOnDataAccess reports whether a file is dataless (evicted to iCloud Drive, flag SF_DATALESS in Stat_t.Flags). ExtendedFileInfo is built by fs.ExtendedStat from an os.FileInfo, and this method type-asserts the stored Sys() value to *syscall.Stat_t; when the underlying FileInfo came from a different source, the assertion fails and the error names the file.","triggerScenarios":"Constructing ExtendedFileInfo from a custom or wrapped os.FileInfo whose Sys() is nil or another type (test fakes, in-memory filesystems, archive walkers); running darwin-specific logic against FileInfo produced by another platform's stat path; restorer code passing archived metadata instead of live stat results.","commonSituations":"Unit tests with mock filesystems; embedding restic's fs package behind a virtual FS; cross-platform code that forgot a runtime.GOOS gate before calling the darwin-only method.","solutions":["Build ExtendedFileInfo only from os.Stat/os.Lstat results on the matching GOOS","When wrapping os.FileInfo, forward the original Sys() value unchanged","Handle the (bool, error) pair: on error, treat the file as locally available instead of failing the walk","Gate cloud-eviction checks behind runtime.GOOS == \"darwin\""],"exampleFix":"// before\nfi := myWrappedFileInfo{...} // Sys() returns nil\nefi := fs.ExtendedStat(fi)\nrecall, err := efi.RecallOnDataAccess() // always errors\n\n// after: only inspect files backed by the real darwin stat\nif _, ok := fi.Sys().(*syscall.Stat_t); !ok {\n    recall = false // cannot know; do not force a download\n} else {\n    recall, err = fs.ExtendedStat(fi).RecallOnDataAccess()\n}","handlingStrategy":"type-guard","validationCode":"// ensure the FileInfo originates from the real darwin filesystem layer\nif _, ok := fi.Sys().(*syscall.Stat_t); !ok {\n    recall = false // cannot inspect dataless state on a wrapped FileInfo\n}","typeGuard":"func hasDarwinStatT(fi os.FileInfo) bool {\n    _, ok := fi.Sys().(*syscall.Stat_t)\n    return ok\n}","tryCatchPattern":"recall, err := efi.RecallOnDataAccess()\nif err != nil {\n    // missing platform stat data: treat as locally available\n    recall = false\n}","preventionTips":["Forward Sys() unchanged when wrapping os.FileInfo","Derive ExtendedFileInfo only from os.Stat/os.Lstat on the target GOOS","Always check the (bool, error) pair instead of assuming success","Gate platform-specific checks behind runtime.GOOS"],"tags":["darwin","macos","file-info","type-assertion","icloud","dataless"],"backgroundTag":null,"analyzedSha":"a80be1478a4c537f8396e0db2b05120aa78f11e0","analyzedAt":"2026-08-15T15:30:29.928Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}