{"record":{"id":"a68aa76d9079d97d","repo":"docker/compose","slug":"walking-q-w","errorCode":null,"errorMessage":"walking %q: %w","messagePattern":"walking %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sync/tar.go","lineNumber":272,"sourceCode":"\t\t\treturn nil, nil\n\t\t}\n\t\treturn nil, err\n\t}\n\n\tlocalPathIsDir := localInfo.IsDir()\n\tif localPathIsDir {\n\t\t// Make sure we can trim this off filenames to get valid relative filepaths\n\t\tif !strings.HasSuffix(localPath, string(filepath.Separator)) {\n\t\t\tlocalPath += string(filepath.Separator)\n\t\t}\n\t}\n\n\tcontainerPath = strings.TrimPrefix(containerPath, \"/\")\n\n\tresult := make([]archiveEntry, 0)\n\terr = filepath.Walk(localPath, func(curLocalPath string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"walking %q: %w\", curLocalPath, err)\n\t\t}\n\n\t\tlinkname := \"\"\n\t\tif info.Mode()&os.ModeSymlink != 0 {\n\t\t\tvar err error\n\t\t\tlinkname, err = os.Readlink(curLocalPath)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tvar name string\n\t\t//nolint:gocritic\n\t\tif localPathIsDir {\n\t\t\t// Name of file in tar should be relative to source directory...\n\t\t\ttmp, err := filepath.Rel(localPath, curLocalPath)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"making %q relative to %q: %w\", curLocalPath, localPath, err)","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/internal/sync/tar.go#L254-L290","documentation":"entriesForPath enumerates a synced directory recursively with filepath.Walk. Any error the walk itself reports (unreadable directory during readdir, permission denied descending) is wrapped as 'walking %q' for the current path. It is the directory-traversal analogue of the stat errors.","triggerScenarios":"filepath.Walk's callback receiving a non-nil err: a subdirectory without read/execute permission for the compose process, a directory removed between listing and descent, or EIO from the filesystem during readdir.","commonSituations":"Sync roots containing root-owned directories (created by an earlier privileged container) that an unprivileged compose run cannot enumerate; node_modules with restrictive modes; flaky NFS mounts.","solutions":["Grant read+traverse on the failing subdirectory: chmod u+rX (the message names curLocalPath exactly)","Exclude unreadable subtrees from the PathMapping (e.g. do not sync .git or root-owned build outputs)","If the directory was transiently removed, simply retry the sync — the fresh walk will not see it","Repair/remount faulty network filesystems before syncing"],"exampleFix":"# the error names the exact unreadable path\nls '/path/from/error'   # -> Permission denied\nchmod u+rX '/path/from/error'","handlingStrategy":"validation","validationCode":"// pre-walk the sync root with the compose user; fail fast on unreadable dirs\nerr := filepath.Walk(root, func(p string, fi os.FileInfo, err error) error {\n    if err != nil { return err }\n    if fi.IsDir() && fi.Mode()&0500 != 0500 { return fmt.Errorf(\"not readable/traversable: %s\", p) }\n    return nil\n})","typeGuard":null,"tryCatchPattern":"// extract curLocalPath from the wrap, chmod it, re-run Sync","preventionTips":["chmod u+rX synced directories after privileged containers write into them","Scope sync mappings tightly to owned subtrees"],"tags":["filesystem","permissions","walk","sync","go"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}