{"record":{"id":"3fe074ffc284d02b","repo":"docker/compose","slug":"invalid-git-subdirectory-path-w","errorCode":null,"errorMessage":"invalid git subdirectory path: %w","messagePattern":"invalid git subdirectory path: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/remote/git.go","lineNumber":162,"sourceCode":"\t\treturn fmt.Errorf(\"git subdirectory must be relative, got: %s\", subDir)\n\t}\n\n\tif cleanSubDir == \"..\" || strings.HasPrefix(cleanSubDir, \"../\") || strings.HasPrefix(cleanSubDir, \"..\\\\\") {\n\t\treturn fmt.Errorf(\"git subdirectory path traversal detected: %s\", subDir)\n\t}\n\n\tif len(cleanSubDir) >= 2 && cleanSubDir[1] == ':' {\n\t\treturn fmt.Errorf(\"git subdirectory must be relative, got: %s\", subDir)\n\t}\n\n\ttargetPath := filepath.Join(base, cleanSubDir)\n\tcleanBase := filepath.Clean(base)\n\tcleanTarget := filepath.Clean(targetPath)\n\n\t// Ensure the target starts with the base path\n\trelPath, err := filepath.Rel(cleanBase, cleanTarget)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid git subdirectory path: %w\", err)\n\t}\n\n\tif relPath == \"..\" || strings.HasPrefix(relPath, \"../\") || strings.HasPrefix(relPath, \"..\\\\\") {\n\t\treturn fmt.Errorf(\"git subdirectory escapes base directory: %s\", subDir)\n\t}\n\n\treturn nil\n}\n\nfunc (g gitRemoteLoader) resolveGitRef(ctx context.Context, path string, ref *gitutil.GitRef) error {\n\tif !commitSHA.MatchString(ref.Ref) {\n\t\tcmd := exec.CommandContext(ctx, \"git\", \"ls-remote\", \"--exit-code\", ref.Remote, ref.Ref)\n\t\tcmd.Env = g.gitCommandEnv()\n\t\tout, err := cmd.CombinedOutput()\n\t\tif err != nil {\n\t\t\tif cmd.ProcessState.ExitCode() == 2 {\n\t\t\t\treturn fmt.Errorf(\"repository does not contain ref %s, output: %q: %w\", path, string(out), err)\n\t\t\t}","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/remote/git.go#L144-L180","documentation":"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.","triggerScenarios":"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.","commonSituations":"Exotic Windows path inputs (UNC vs drive paths) reaching the git include loader; essentially a robustness guard rather than a user-facing condition.","solutions":["Use plain forward-slash relative sub-paths in git include fragments","Avoid mixing UNC (`\\\\server\\share`) and drive-letter paths in compose include configuration"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use plain relative sub-paths with forward slashes in git include fragments","Avoid mixing UNC and drive-letter path styles anywhere in compose configuration"],"tags":["compose","git-remote","windows","path-validation"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}