gohugoio/hugo · error
failed to map git repo for module %s: %v
Error message
failed to map git repo for module %s: %v
What it means
After successfully cloning a module's origin repo into the GitInfo cache, Hugo runs gitmap over that clone at the module's pinned revision (origin.Hash) to build a filename→commit map. This error means that mapping step failed — the clone exists but git log/rev operations against the recorded revision did not succeed.
Source
Thrown at hugolib/gitinfo.go:176
}
func (g *gitInfo) loadModuleRepos(cfg gitInfoConfig) error {
for _, mod := range cfg.Modules {
if !isGitModule(mod) {
continue
}
loadGitInfo := sync.OnceValues(func() (*gitmap.GitRepo, error) {
origin := mod.Origin()
cloneDir, err := ensureClone(cfg, origin)
if err != nil {
return nil, fmt.Errorf("failed to clone %s: %v", origin.URL, err)
}
repo, err := mapModuleRepo(cfg, cloneDir, origin.Hash)
if err != nil {
return nil, fmt.Errorf("failed to map git repo for module %s: %v", mod.Path(), err)
}
return repo, nil
})
g.moduleRepoLoaders[mod.Dir()] = loadGitInfo
}
return nil
}
// ensureClone ensures a blobless clone of the module's origin repo exists in the cache.
func ensureClone(cfg gitInfoConfig, origin modules.ModuleOrigin) (string, error) {
key := "repo_" + hashing.XxHashFromStringHexEncoded(origin.URL)
info, err := cfg.GitInfoCache.GetOrCreateInfo(key, func(id string) error {
cloneDir := cfg.GitInfoCache.AbsFilenameFromID(id)
if err := os.MkdirAll(cloneDir, 0o777); err != nil {
return err
}View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Clear the GitInfo cache (remove the repo_* directories under Hugo's cache dir, or `hugo --gc` / delete cacheDir) so the clone is recreated fresh.
- Run `hugo mod get -u <module>` to re-resolve the module to a revision that exists upstream.
- Check the wrapped git error for the specific revision; verify it exists with `git ls-remote <origin>`.
- If the upstream history was rewritten, pin the module to a valid tag/commit in your module config.
Defensive patterns
Strategy: fallback
Validate before calling
// confirm each module dir is inside a git work tree
out, err := exec.Command("git", "-C", moduleDir, "rev-parse", "--is-inside-work-tree").Output()
if err != nil || strings.TrimSpace(string(out)) != "true" {
log.Printf("module %s not a git repo; GitInfo unavailable", moduleDir)
} Try / catch
if err := build(); err != nil && strings.Contains(err.Error(), "failed to map git repo for module") {
// fall back: build without git info for vendored/non-git modules
cfg.Set("enableGitInfo", false)
err = build()
} Prevention
- Don't enable GitInfo when modules are vendored or fetched without .git directories
- Use full (non-shallow) clones in CI so module git metadata is complete
- Verify each mounted module path is a real git checkout before enabling GitInfo
When it happens
Trigger: mapModuleRepo failing inside the sync.OnceValues loader in loadModuleRepos: the module's pinned hash (from go.sum/module origin metadata) not present in the blobless clone (e.g. force-pushed or GC'd upstream), a stale/corrupted cached clone, or git command failures when gitmap walks the revision.
Common situations: Module upstream rewrote history so the pinned commit no longer exists; the GitInfo cache holds an old clone that predates new commits and was not fetched; interrupted earlier clone leaving a broken repo in the cache; version-pinned modules whose tags were moved.
Related errors
- failed to clone %s: %v
- failed to load Git data: %w
- failed to load modules: %w
- failed to create config from modules config: %w
- no modules loaded (need at least the main module)
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/fd73932ebf00c5f6.json.
Report an issue: GitHub ↗.