docker/compose · error

making %q relative to %q: %w

Error message

making %q relative to %q: %w

What it means

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.

Source

Thrown at internal/sync/tar.go:290

			return fmt.Errorf("walking %q: %w", curLocalPath, err)
		}

		linkname := ""
		if info.Mode()&os.ModeSymlink != 0 {
			var err error
			linkname, err = os.Readlink(curLocalPath)
			if err != nil {
				return err
			}
		}

		var name string
		//nolint:gocritic
		if localPathIsDir {
			// Name of file in tar should be relative to source directory...
			tmp, err := filepath.Rel(localPath, curLocalPath)
			if err != nil {
				return fmt.Errorf("making %q relative to %q: %w", curLocalPath, localPath, err)
			}
			// ...and live inside `dest`
			name = path.Join(containerPath, filepath.ToSlash(tmp))
		} else if strings.HasSuffix(containerPath, "/") {
			name = containerPath + filepath.Base(curLocalPath)
		} else {
			name = containerPath
		}

		header, err := archive.FileInfoHeader(name, info, linkname)
		if err != nil {
			// Not all types of files are allowed in a tarball. That's OK.
			// Mimic the Docker behavior and just skip the file.
			return nil
		}

		result = append(result, archiveEntry{
			path:   curLocalPath,

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. On Windows, remove subst/junction indirections so the walk root and all children share one canonical volume path
  2. 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
  3. Move the synced content to a path without drive-mapping tricks and retry
  4. If reproducible, capture curLocalPath and localPath from the message and test filepath.Rel on them directly to identify the mismatch

Example fix

// before (Windows): mapping host path via subst drive X:\
// after: map the real volume path
//   C:\work\project  instead of  X:\  (subst X: C:\work)
// then restart docker compose watch
Defensive patterns

Strategy: validation

Validate before calling

// normalize the mapping host path before Sync on Windows: absolute, single volume, no trailing separators
abs, err := filepath.Abs(hostPath)
if err != nil || filepath.VolumeName(abs) == "" { return fmt.Errorf("bad sync root: %s", hostPath) }

Try / catch

// 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

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/e52dcb5e2f02bcdf. Report an issue: GitHub.