{"id":"f7a470e383d711a7","repo":"gohugoio/hugo","slug":"git-clone-s-w-s","errorCode":null,"errorMessage":"git clone %s: %w: %s","messagePattern":"git clone (.+?): %w: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hugolib/gitinfo.go","lineNumber":214,"sourceCode":"\t\tvar stderr bytes.Buffer\n\t\targs := []any{\n\t\t\t\"clone\",\n\t\t\t\"--filter=blob:none\",\n\t\t\t\"--no-checkout\",\n\t\t\torigin.URL,\n\t\t\tcloneDir,\n\t\t\thexec.WithStdout(io.Discard),\n\t\t\thexec.WithStderr(&stderr),\n\t\t}\n\n\t\tcfg.Logger.Infof(\"Cloning gitinfo for repo %s into cache\", origin.URL)\n\n\t\tcmd, err := cfg.Deps.ExecHelper.New(\"git\", args...)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"git clone: %w\", err)\n\t\t}\n\t\tif err := cmd.Run(); err != nil {\n\t\t\treturn fmt.Errorf(\"git clone %s: %w: %s\", origin.URL, err, stderr.String())\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn cfg.GitInfoCache.AbsFilenameFromID(info.Name), nil\n}\n\nfunc mapModuleRepo(cfg gitInfoConfig, repoDir, revision string) (*gitmap.GitRepo, error) {\n\topts := gitmap.Options{\n\t\tRepository: repoDir,\n\t\tRevision:   revision,\n\t\tGetGitCommandFunc: func(stdout, stderr io.Writer, args ...string) (gitmap.Runner, error) {\n\t\t\tvar argsv []any\n\t\t\tfor _, arg := range args {\n\t\t\t\targsv = append(argsv, arg)\n\t\t\t}","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/hugolib/gitinfo.go#L196-L232","documentation":"The low-level failure behind module GitInfo cloning: the `git clone --filter=blob:none --no-checkout <url> <dir>` subprocess exited non-zero. Hugo wraps the exit error and appends git's captured stderr so the real cause (auth, DNS, not-a-repo) is visible in the message.","triggerScenarios":"cmd.Run() failing in ensureClone: 'Repository not found'/authentication prompts for private repos in non-interactive builds, DNS or proxy failures, an origin URL that isn't a git repo, git versions too old to support --filter=blob:none (pre-2.19), or disk-full in the cache directory.","commonSituations":"Private Hugo module repos in CI without a token-based credential setup (GIT_ASKPASS unset, so clone fails instead of prompting); corporate proxies blocking git over https; extremely old git in a minimal container image.","solutions":["Read the stderr appended to the message — it states the git-level cause; fix that (credentials, URL, network).","For private modules in CI, configure a token, e.g. `git config --global url.\"https://x:${TOKEN}@github.com/\".insteadOf \"https://github.com/\"`.","Upgrade git to ≥2.19 so partial clone (--filter=blob:none) is supported.","Verify the origin URL manually with `git clone --filter=blob:none --no-checkout <url> /tmp/t`."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-flight the exact clone Hugo will run\ncmd := exec.Command(\"git\", \"clone\", \"--depth=1\", repoURL, os.TempDir()+\"/probe\")\nif out, err := cmd.CombinedOutput(); err != nil {\n    log.Fatalf(\"clone pre-check failed: %v: %s\", err, out)\n}","typeGuard":null,"tryCatchPattern":"err := build()\nif err != nil && strings.Contains(err.Error(), \"git clone\") {\n    // stderr is embedded in the error — inspect for auth vs network vs bad URL\n    if strings.Contains(err.Error(), \"Authentication failed\") { /* fix credentials, don't retry */ } else { retryWithBackoff(build) }\n}","preventionTips":["Read the embedded git stderr in the error to distinguish auth, DNS, and bad-URL causes before retrying","Configure git credential helpers or SSH keys in CI rather than interactive auth","Retry only network-class failures with backoff; auth and 404 errors are permanent"],"tags":["hugo","git","clone","authentication","ci"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}