gohugoio/hugo · error
cannot vendor module %q, need at least one mount
Error message
cannot vendor module %q, need at least one mount
What it means
Raised by `hugo mod vendor` (modules/client.go:229) when a module selected for vendoring reports no mounts. Vendoring copies each mount's files into _vendor/, so a module with a nil mount set would produce an empty, broken vendor entry; Hugo fails fast instead (see issue 8239).
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 8a468df065)
Solutions
- Give the module at least one mountable directory (content, layouts, assets, static, ...) or an explicit [[module.mounts]] entry in its config.
- If the import shouldn't be vendored at all, add it to module.noVendor in the project config.
- Remove the import if it's not a real Hugo module.
- Run hugo mod graph to confirm which module the reported path/version refers to.
Example fix
# in the offending module's hugo.toml [[module.mounts]] source = "layouts" target = "layouts"
Defensive patterns
Strategy: validation
Validate before calling
// Ensure every module to be vendored has at least one mount
for _, m := range client.Graph() {
if len(m.Mounts()) == 0 {
return fmt.Errorf("module %s has no mounts; add [module.mounts] or remove the import before vendoring", m.Path())
}
} Try / catch
if err := client.Vendor(); err != nil {
if strings.Contains(err.Error(), "need at least one mount") {
return fmt.Errorf("a module imports nothing usable — add mounts or drop the import: %w", err)
}
return err
} Prevention
- Only import modules that actually provide Hugo components; drop pure-Go dependencies from [module.imports]
- Run `hugo mod graph` before `hugo mod vendor` to confirm each module contributes mounts
- Add explicit mounts in the import config when a module lacks its own hugo config
When it happens
Trigger: Running hugo mod vendor when a collected module (t.Owner() != nil, is a Go module or has vendor enabled, not excluded by noVendor) has Mounts() == nil — typically a module whose config couldn't produce any mounts, e.g. an empty module or one whose declared dirs don't exist.
Common situations: Vendoring a freshly created or empty module repo with no content/layouts/etc. directories and no explicit mounts; importing a Go module that isn't actually a Hugo module; a module whose hugo config disables all default mounts.
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/c7616be4ad8e671b.json.
Report an issue: GitHub ↗.