gohugoio/hugo · error

failed to apply mounts for project: %w

Error message

failed to apply mounts for project: %w

What it means

In `collector.addAndRecurse` (modules/collect.go:370), before recursing into imports, Hugo applies the project's own mount configuration (`module.mounts` mapping source dirs to content/assets/layouts etc.). If `applyMounts` fails for the project module, the error is wrapped as `failed to apply mounts for project`. The wrapped cause typically comes from validating mounts or scanning the project dir for JS config files.

Source

Thrown at modules/collect.go:370

	if !moduleImport.IgnoreConfig {
		if err := c.applyThemeConfig(ma); err != nil {
			return nil, err
		}
	}

	if err := c.applyMounts(moduleImport, ma); err != nil {
		return nil, err
	}

	return ma, nil
}

func (c *collector) addAndRecurse(owner *moduleAdapter) error {
	moduleConfig := owner.Config()
	if owner.projectMod {
		if err := c.applyMounts(Import{}, owner); err != nil {
			return fmt.Errorf("failed to apply mounts for project: %w", err)
		}
	}
	seen := make(map[pathVersionKey]bool)
	for _, moduleImport := range moduleConfig.Imports {
		if moduleImport.Disable {
			continue
		}

		// Prevent cyclic references.
		if v := c.isPathSeen(moduleImport.Path, owner); v != nil && v != owner {
			continue
		}

		tc, err := c.getAndCreateModule(owner, moduleImport)
		if err != nil {
			return err
		}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Inspect the wrapped inner error text — it names the invalid mount or unreadable path.
  2. Validate each `[[module.mounts]]`: `source` must exist relative to the project, `target` must begin with a valid component root (content, assets, layouts, static, data, i18n, archetypes).
  3. Remember that specifying any mounts for a component replaces the defaults — re-add defaults you still need.
  4. Check read permissions on the project working directory.

Example fix

# before
[[module.mounts]]
source = "src/content"
target = "contents"   # invalid target root
# after
[[module.mounts]]
source = "src/content"
target = "content"
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate mount config shape before build: source/target both non-empty,
// target rooted in a known component (content, layouts, static, assets, ...)

Try / catch

if err := applyMounts(); err != nil {
    // %w-wrapped: unwrap for root cause
    log.Printf("project mounts failed: %v", errors.Unwrap(err))
    return err
}

Prevention

When it happens

Trigger: `applyMounts(Import{}, owner)` failing on the project module during collection: invalid `module.mounts` entries (empty source/target, disallowed target root), or failure opening/reading the project directory when auto-mounting common JS configs (postcss/babel/tailwind config detection).

Common situations: Hand-written `[[module.mounts]]` blocks with a typo'd or unsupported `target` (must start with content/assets/layouts/static/data/i18n/archetypes); a source path with wrong type; project directory permission problems; defining one mount and unintentionally dropping defaults, then referencing invalid entries.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/a0c4c559247e906b.json. Report an issue: GitHub ↗.