gohugoio/hugo · error

%s: mount target must be one of: %v

Error message

%s: mount target must be one of: %v

What it means

When normalizing module mounts, Hugo verifies that the first path segment of each mount's `target` is one of the predefined Hugo component folders (content, data, layouts, i18n, archetypes, assets, static). A target outside that set has no meaning in Hugo's virtual filesystem, so collection fails with the list of valid folders.

Source

Thrown at modules/collect.go:871

					_, err := c.fs.Stat(sourceDir)
					if err != nil {
						continue
					}
					mnt.Source = sourceDir
				} else {
					continue
				}
			}
		}

		// Verify that target points to one of the predefined component dirs
		targetBase := mnt.Target
		idxPathSep := strings.Index(mnt.Target, string(os.PathSeparator))
		if idxPathSep != -1 {
			targetBase = mnt.Target[0:idxPathSep]
		}
		if !files.IsComponentFolder(targetBase) {
			return nil, fmt.Errorf("%s: mount target must be one of: %v", errMsg, files.ComponentFolders)
		}

		if err := mnt.init(c.logger.Logger()); err != nil {
			return nil, fmt.Errorf("%s: %w", errMsg, err)
		}

		out = append(out, mnt)
	}

	return out, nil
}

func (c *collector) wrapModuleNotFound(err error) error {
	if c.Client.ccfg.IgnoreModuleDoesNotExist {
		return nil
	}
	err = fmt.Errorf(err.Error()+": %w", ErrNotExist)
	if c.GoModulesFilename == "" {

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Fix the mount `target` so it starts with one of: content, data, layouts, i18n, archetypes, assets, static (subpaths under those are fine, e.g. `assets/js`).
  2. Check you didn't swap `source` and `target` in the mount block.
  3. If you wanted a custom output location, mount into `static` or `assets` and handle placement via Hugo pipes/templates instead.

Example fix

# before
[[module.mounts]]
source = "dist"
target = "public/js"

# after
[[module.mounts]]
source = "dist"
target = "assets/js"
Defensive patterns

Strategy: validation

Validate before calling

var validTargets = map[string]bool{"content": true, "data": true, "layouts": true, "i18n": true, "archetypes": true, "assets": true, "static": true}
for _, m := range cfg.Mounts {
    root := strings.SplitN(filepath.ToSlash(m.Target), "/", 2)[0]
    if !validTargets[root] {
        return fmt.Errorf("invalid mount target %q", m.Target)
    }
}

Prevention

When it happens

Trigger: A `[[module.mounts]]` entry (in project, theme, or module config) whose `target` first segment is not a component folder — e.g. `target = "public"`, `target = "themes/x"`, a typo like `layout` or `contents`, or an absolute target path.

Common situations: Typos in the target (`asset` vs `assets`); trying to mount into the output/publish dir; confusing `source` and `target` order; using pre-Hugo-modules directory names or custom directories not in ComponentFolders.

Related errors


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