docker/compose · error

invalid git subdirectory path: %w

Error message

invalid git subdirectory path: %w

What it means

Defensive fallback inside `validateGitSubDir`: `filepath.Rel(cleanBase, cleanTarget)` returned an error, which can only happen when the two cleaned paths have no valid relative relationship (e.g. mixed absolute/relative base forms on Windows). The raw error is wrapped with this message.

Source

Thrown at pkg/remote/git.go:162

		return fmt.Errorf("git subdirectory must be relative, got: %s", subDir)
	}

	if cleanSubDir == ".." || strings.HasPrefix(cleanSubDir, "../") || strings.HasPrefix(cleanSubDir, "..\\") {
		return fmt.Errorf("git subdirectory path traversal detected: %s", subDir)
	}

	if len(cleanSubDir) >= 2 && cleanSubDir[1] == ':' {
		return fmt.Errorf("git subdirectory must be relative, got: %s", subDir)
	}

	targetPath := filepath.Join(base, cleanSubDir)
	cleanBase := filepath.Clean(base)
	cleanTarget := filepath.Clean(targetPath)

	// Ensure the target starts with the base path
	relPath, err := filepath.Rel(cleanBase, cleanTarget)
	if err != nil {
		return fmt.Errorf("invalid git subdirectory path: %w", err)
	}

	if relPath == ".." || strings.HasPrefix(relPath, "../") || strings.HasPrefix(relPath, "..\\") {
		return fmt.Errorf("git subdirectory escapes base directory: %s", subDir)
	}

	return nil
}

func (g gitRemoteLoader) resolveGitRef(ctx context.Context, path string, ref *gitutil.GitRef) error {
	if !commitSHA.MatchString(ref.Ref) {
		cmd := exec.CommandContext(ctx, "git", "ls-remote", "--exit-code", ref.Remote, ref.Ref)
		cmd.Env = g.gitCommandEnv()
		out, err := cmd.CombinedOutput()
		if err != nil {
			if cmd.ProcessState.ExitCode() == 2 {
				return fmt.Errorf("repository does not contain ref %s, output: %q: %w", path, string(out), err)
			}

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Use plain forward-slash relative sub-paths in git include fragments
  2. Avoid mixing UNC (`\\server\share`) and drive-letter paths in compose include configuration
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Base and target end up on different Windows drives or one path is volume-relative (`\foo`) while the other is drive-absolute, making `filepath.Rel` fail. On Linux this is nearly unreachable because both are derived by joining the same base.

Common situations: Exotic Windows path inputs (UNC vs drive paths) reaching the git include loader; essentially a robustness guard rather than a user-facing condition.

Related errors


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