gohugoio/hugo · error
cannot vendor module
Error message
cannot vendor module %q, need at least one mount
What it means
Returned by Client.Vendor when a module to be vendored has t.Mounts() == nil. Vendoring copies each declared mount's source into _vendor, so a module with no mounts gives Hugo nothing to copy; this is treated as an error condition (see issue #8239) rather than silently producing an empty vendor entry.
Solutions
- Add at least one [[module.mounts]] entry in the offending module's config (source/target/language).
- Identify the module via the printed PathVersionQuery in the error, then edit that module.
- If the module needs no Hugo assets, exclude it from vendoring with noVendor in your top-level [module] config.
Example fix
# before (in theme module config) # no [[module.mounts]] declared # after [[module.mounts]] source = "layouts" target = "layouts" [[module.mounts]] source = "assets" target = "assets"
Defensive patterns
Strategy: validation
Validate before calling
// Ensure modules you intend to vendor have at least one mount.
func moduleHasMounts(m Module) bool {
return m.Mounts() != nil && len(m.Mounts()) > 0
} Type guard
func isVendorableModule(m Module) bool {
return (m.IsGoMod() || m.Vendor()) && m.Mounts() != nil
} Try / catch
if err := client.Vendor(); err != nil {
if strings.Contains(err.Error(), "need at least one mount") {
// identify module, add mounts to its config, or exclude via noVendor
}
} Prevention
- Always declare [[module.mounts]] in any theme/component intended to be vendored.
- Use [module] noVendor to skip modules that need no Hugo assets.
When it happens
Trigger: Running `hugo mod vendor` (Client.Vendor) on a project where a dependency module is a Go module/theme (t.IsGoMod() or t.Vendor() true) and is not excluded by noVendor, but declares no [[module.mounts]] (its Mounts() returns nil).
Common situations: A theme/component module whose hugo.toml/go.mod omits the [[mounts]] section; a module that is pure Go (no Hugo assets) being pulled into the Hugo module graph; switching a theme to module form without adding mounts.
Related errors
- could not determine content directory for
- failed to apply mounts for project
- failed to vendor module
- invalid module config for
- : : mount source must be a local path for modules/themes
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/c7616be4ad8e671b.
Report an issue: GitHub.
Appendix: source
Thrown at modules/client.go:229
if t.Owner() == nil {
// This is the project.
continue
}
if c.shouldNotVendor(t.PathVersionQuery(false)) || c.shouldNotVendor(t.PathVersionQuery(true)) {
continue
}
if !t.IsGoMod() && !t.Vendor() {
// We currently do not vendor components living in the
// theme directory, see https://github.com/gohugoio/hugo/issues/5993
continue
}
// See https://github.com/gohugoio/hugo/issues/8239
// This is an error situation. We need something to vendor.
if t.Mounts() == nil {
return fmt.Errorf("cannot vendor module %q, need at least one mount", t.PathVersionQuery(false))
}
fmt.Fprintln(&modulesContent, "# "+t.PathVersionQuery(true)+" "+t.Version())
dir := t.Dir()
for _, mount := range t.Mounts() {
sourceFilename := filepath.Join(dir, mount.Source)
targetFilename := filepath.Join(vendorDir, t.PathVersionQuery(true), mount.Source)
fi, err := c.fs.Stat(sourceFilename)
if err != nil {
return fmt.Errorf("failed to vendor module: %w", err)
}
if fi.IsDir() {
if err := hugio.CopyDir(c.fs, sourceFilename, targetFilename, nil); err != nil {
return fmt.Errorf("failed to copy module to vendor dir: %w", err)
}View on GitHub (pinned to 52c9bd7908)