gohugoio/hugo · error
%q not found
Error message
%q not found
What it means
At modules/collect.go:331, after Hugo has resolved an import to a concrete directory (from a replacement, vendor entry, go module cache, or themesDir), it verifies the directory actually exists on disk. If not, it fails with `%q not found`, wrapped with `ErrNotExist` via `wrapModuleNotFound`. This is a final sanity check that the resolved location is real.
Source
Thrown at modules/collect.go:331
// Fall back to project/themes/<mymodule>
if moduleDir == "" {
var err error
moduleDir, err = c.createThemeDirname(modulePath, owner.projectMod || moduleImport.pathProjectReplaced)
if err != nil {
c.err = err
return nil, nil
}
if found, _ := afero.Exists(c.fs, moduleDir); !found {
//lint:ignore ST1005 end user message.
c.err = c.wrapModuleNotFound(fmt.Errorf(`module %q not found in %q; either add it as a Hugo Module or store it in %q.`, modulePath, moduleDir, c.ccfg.ThemesDir))
return nil, nil
}
}
}
}
if found, _ := afero.Exists(c.fs, moduleDir); !found {
c.err = c.wrapModuleNotFound(fmt.Errorf("%q not found", moduleDir))
return nil, nil
}
if !strings.HasSuffix(moduleDir, fileSeparator) {
moduleDir += fileSeparator
}
ma := &moduleAdapter{
dir: moduleDir,
vendor: vendored,
gomod: mod,
version: versionMod,
versionQuery: requestedVersionQuery,
// This may be the owner of the _vendor dir
owner: realOwner,
}
if mod == nil {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Check the quoted path in the error — create it or fix the `module.replacements` mapping that produced it.
- If vendored, re-run `hugo mod vendor` (or delete `_vendor`) to regenerate a consistent vendor tree.
- Re-download modules with `hugo mod get` if the Go module cache was cleaned.
- Avoid absolute machine-specific replacement paths in shared config; use env-specific config or relative paths.
Example fix
# before [module] replacements = "github.com/org/theme -> /Users/alice/dev/theme" # CI has no such dir # after (relative to project, exists in repo) [module] replacements = "github.com/org/theme -> ../theme"
Defensive patterns
Strategy: validation
Validate before calling
if fi, err := os.Stat(mountSource); err != nil || !fi.IsDir() {
return fmt.Errorf("mount source %q missing", mountSource)
} Try / catch
if err := collectMounts(); err != nil {
if strings.Contains(err.Error(), "not found") {
// a mount source dir or module component is absent
}
return err
} Prevention
- Verify every `[[module.mounts]]` source directory exists before building
- Don't reference optional dirs in mounts; create them or remove the mount
- Check .gitignore/CI checkout isn't excluding directories the config mounts
When it happens
Trigger: Module collection where the resolved `moduleDir` doesn't exist: a `module.replacements` target pointing at a missing local directory, a stale `_vendor/modules.txt` entry whose files were deleted, or a module-cache path removed by `go clean -modcache`.
Common situations: Replacement directives with machine-specific absolute paths shared across machines/CI; partially committed `_vendor` directories (modules.txt present, files missing); cleaning the Go module cache while Hugo still references cached dirs.
Related errors
- failed to vendor module: %w
- failed to copy module to vendor dir: %w
- failed to make target dir: %w
- failed to copy module file to vendor: %w
- failed to copy resources to vendor dir: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/e64c4f3929e7cab8.json.
Report an issue: GitHub ↗.