{"record":{"id":"b543f6182d51677a","repo":"yorukot/superfile","slug":"cannot-access-source-path-s-w","errorCode":null,"errorMessage":"cannot access source path %s: %w","messagePattern":"cannot access source path (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/internal/file_operations_compress.go","lineNumber":28,"sourceCode":"\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\ttea \"charm.land/bubbletea/v2\"\n\n\t\"github.com/yorukot/superfile/src/internal/ui/notify\"\n\t\"github.com/yorukot/superfile/src/internal/ui/processbar\"\n)\n\nfunc validateCompressOperation(sources []string) (int, error) {\n\ttotalFiles := 0\n\tfor _, src := range sources {\n\t\tstat, err := os.Stat(src)\n\t\tif os.IsNotExist(err) {\n\t\t\treturn 0, fmt.Errorf(\"source path does not exist: %s\", src)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn 0, fmt.Errorf(\"cannot access source path %s: %w\", src, err)\n\t\t}\n\t\tif !stat.IsDir() {\n\t\t\tif err = checkFileReadable(src); err != nil {\n\t\t\t\tslog.Error(\"the file is not readable\", \"error\", err)\n\t\t\t\treturn 0, fmt.Errorf(\"the file is not readable: %s\", err.Error())\n\t\t\t}\n\t\t}\n\t\tcount, err := countReadableFiles(src)\n\t\tif err != nil {\n\t\t\tslog.Error(\"Error while zip file count files \", \"error\", err)\n\t\t\treturn 0, fmt.Errorf(\"error while counting files for %s: %s\", src, err.Error())\n\t\t}\n\t\ttotalFiles += count\n\t}\n\treturn totalFiles, nil\n}\n\nfunc (m *model) getCompressSelectedFilesCmd() tea.Cmd {","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/yorukot/superfile/blob/b72f550bc6e75913f48eb49fdd258e1a2df2fe88/src/internal/file_operations_compress.go#L10-L46","documentation":"validateCompressOperation wraps an os.Stat error that is NOT 'not exist' for a compression source — meaning the path exists but cannot be accessed (permission denied on a parent dir, I/O error, or a broken path component). The original error is preserved with %w.","triggerScenarios":"os.Stat fails with EACCES (no execute permission on a parent directory), EIO on flaky storage, or symlink loops / other stat errors on a source passed to zipSources.","commonSituations":"Compressing files under a directory the user can traverse only partially; NFS/network mounts returning stale handles; directories with restrictive ACLs.","solutions":["Inspect the wrapped cause with errors.As(*fs.PathError) to see which syscall/errno failed.","Add x (traverse) permission on parent directories: chmod +x on each ancestor of the source.","Remount stale network shares or fix broken symlinks in the path.","Run as a user with sufficient rights, or exclude inaccessible sources from the selection."],"exampleFix":"// before\nvar pe *fs.PathError\nif errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {\n    return fmt.Errorf(\"cannot access %s: check directory execute permissions\", pe.Path)\n}","handlingStrategy":"validation","validationCode":"for _, s := range sources {\n    if _, err := os.Stat(s); err != nil && !errors.Is(err, fs.ErrNotExist) {\n        return fmt.Errorf(\"source %s inaccessible: %w\", s, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := ops.ZipSources(sources, target); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {\n        return fmt.Errorf(\"add execute permission on %s parent dirs\", pe.Path)\n    }\n    return err\n}","preventionTips":["Keep traverse (x) permission on all ancestor directories of sources.","Fix stale NFS/network mounts before compressing from them.","Check for broken symlinks in source paths."],"tags":["go","filesystem","permissions","compress"],"backgroundTag":"permission-denied","analyzedSha":"b72f550bc6e75913f48eb49fdd258e1a2df2fe88","analyzedAt":"2026-09-01T04:38:08.254Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}