{"record":{"id":"e52dcb5e2f02bcdf","repo":"docker/compose","slug":"making-q-relative-to-q-w","errorCode":null,"errorMessage":"making %q relative to %q: %w","messagePattern":"making %q relative to %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sync/tar.go","lineNumber":290,"sourceCode":"\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)\n\t\t\t}\n\t\t\t// ...and live inside `dest`\n\t\t\tname = path.Join(containerPath, filepath.ToSlash(tmp))\n\t\t} else if strings.HasSuffix(containerPath, \"/\") {\n\t\t\tname = containerPath + filepath.Base(curLocalPath)\n\t\t} else {\n\t\t\tname = containerPath\n\t\t}\n\n\t\theader, err := archive.FileInfoHeader(name, info, linkname)\n\t\tif err != nil {\n\t\t\t// Not all types of files are allowed in a tarball. That's OK.\n\t\t\t// Mimic the Docker behavior and just skip the file.\n\t\t\treturn nil\n\t\t}\n\n\t\tresult = append(result, archiveEntry{\n\t\t\tpath:   curLocalPath,","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/internal/sync/tar.go#L272-L308","documentation":"When the mapping root is a directory, each walked file's tar name is computed with filepath.Rel(localPath, curLocalPath). If a walked path cannot be made relative to the walk root, the callback fails with 'making %q relative to %q'. filepath.Rel errors when the two paths are on different volumes or the argument is not lexically reachable — rare inside a single Walk, but possible on Windows across drives or with case/symlink anomalies.","triggerScenarios":"filepath.Rel returning an error for a path produced by walking localPath — in practice: Windows environments where curLocalPath resolves through a different drive letter (subst/junction), or path-normalization mismatches (separator/case) between the walk root and walked entries.","commonSituations":"Windows dev setups with subst drives or junction points inside the sync root; path-length or 8.3 short-name mismatches; exotic case-only renames on case-insensitive filesystems.","solutions":["On Windows, remove subst/junction indirections so the walk root and all children share one canonical volume path","Normalize the PathMapping HostPath (no trailing separators, no short 8.3 names, consistent case) — the code appends a separator itself, so supply a clean absolute path","Move the synced content to a path without drive-mapping tricks and retry","If reproducible, capture curLocalPath and localPath from the message and test filepath.Rel on them directly to identify the mismatch"],"exampleFix":"// before (Windows): mapping host path via subst drive X:\\\n// after: map the real volume path\n//   C:\\work\\project  instead of  X:\\  (subst X: C:\\work)\n// then restart docker compose watch","handlingStrategy":"validation","validationCode":"// normalize the mapping host path before Sync on Windows: absolute, single volume, no trailing separators\nabs, err := filepath.Abs(hostPath)\nif err != nil || filepath.VolumeName(abs) == \"\" { return fmt.Errorf(\"bad sync root: %s\", hostPath) }","typeGuard":null,"tryCatchPattern":"// if hit despite normalization, log both paths from the message and compare volume letters/case; remap the sync root to a canonical path and retry","preventionTips":["Avoid subst drives and junctions inside sync roots on Windows","Pass clean absolute paths in PathMapping.HostPath"],"tags":["windows","filesystem","sync","paths","go"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}