{"record":{"id":"4b703ba17afac8ea","repo":"docker/compose","slug":"unexpected-git-command-output-q","errorCode":null,"errorMessage":"unexpected git command output: %q","messagePattern":"unexpected git command output: %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/remote/git.go","lineNumber":184,"sourceCode":"\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}\n\t\t\treturn fmt.Errorf(\"failed to access repository at %s:\\n %s\", ref.Remote, out)\n\t\t}\n\t\tif len(out) < 40 {\n\t\t\treturn fmt.Errorf(\"unexpected git command output: %q\", string(out))\n\t\t}\n\t\tsha := string(out[:40])\n\t\tif !commitSHA.MatchString(sha) {\n\t\t\treturn fmt.Errorf(\"invalid commit sha %q\", sha)\n\t\t}\n\t\tref.Ref = sha\n\t}\n\treturn nil\n}\n\nfunc (g gitRemoteLoader) checkout(ctx context.Context, path string, ref *gitutil.GitRef) error {\n\terr := os.MkdirAll(path, 0o700)\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = exec.CommandContext(ctx, \"git\", \"init\", path).Run()\n\tif err != nil {\n\t\treturn err","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/remote/git.go#L166-L202","documentation":"`git ls-remote` exited 0 (ref found) but produced fewer than 40 bytes of output, too short to contain a commit SHA. The loader expects `<40-hex-sha>\\t<ref>` lines and treats shorter output as protocol corruption rather than guessing.","triggerScenarios":"A git server or proxy returning an empty/truncated response; unusual git server implementations; output mangled by a wrapper or `GIT_EXTERNAL` tooling in `gitCommandEnv`. Extremely rare with standard git hosts.","commonSituations":"Self-hosted git servers with non-standard smart-HTTP behavior; broken proxies stripping response bodies; intermediary antivirus rewriting output.","solutions":["Run `git ls-remote <remote> <ref>` manually and inspect the raw output length/content","Bypass resolution by pinning the include to a 40-char commit SHA (`#<sha>` skips ls-remote)","Fix the proxy/server that is truncating git protocol responses"],"exampleFix":"# before\ninclude:\n  - path: git://git.internal.corp/repo.git#main\n\n# after (pin SHA, skips ls-remote)\ninclude:\n  - path: git://git.internal.corp/repo.git#1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b","handlingStrategy":"fallback","validationCode":"# sanity-check the server emits a parseable sha line\ngit ls-remote https://git.internal.corp/repo.git HEAD | head -c40 | grep -qE '^[a-f0-9]{40}$' \\\n  || echo \"WARNING: git server output not SHA-prefixed; pin SHAs in includes\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin includes to literal 40-char SHAs to bypass ls-remote parsing entirely","Keep proxies/AV from rewriting git smart-HTTP response bodies"],"tags":["compose","git-remote","git-protocol"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}