gohugoio/hugo · error

unable to process menus for page %q: %w

Error message

unable to process menus for page %q: %w

What it means

`PageMenusFromPage` (navigation/pagemenus.go:44) parses a page's front matter `menus`/`menu` key, which may be a string, a slice of strings, or a map of structured menu entries. When the value is none of those shapes — or a structured entry's value can't be converted to a string map — the underlying cast error is wrapped with the page's path so the user can locate the offending page.

Source

Thrown at navigation/pagemenus.go:73

	if err == nil {
		me.Menu = mname
		pm[mname] = &me
		return pm, nil
	}

	// Could be a slice of strings
	mnames, err := cast.ToStringSliceE(ms)

	if err == nil {
		for _, mname := range mnames {
			me.Menu = mname
			pm[mname] = &me
		}
		return pm, nil
	}

	wrapErr := func(err error) error {
		return fmt.Errorf("unable to process menus for page %q: %w", p.Path(), err)
	}

	// Could be a structured menu entry
	menus, err := hmaps.ToStringMapE(ms)
	if err != nil {
		return pm, wrapErr(err)
	}

	for name, menu := range menus {
		menuEntry := MenuEntry{Menu: name}
		if menu != nil {
			ime, err := hmaps.ToStringMapE(menu)
			if err != nil {
				return pm, wrapErr(err)
			}
			if err := mapstructure.WeakDecode(ime, &menuEntry.MenuConfig); err != nil {
				return pm, err
			}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Open the page named in the error and fix the `menus` key: use a string (`menu: main`), a list of strings, or a map keyed by menu name with entry properties.
  2. Convert site-config-style list entries (`menus: [{name: ...}]`) into the page-front-matter map form (`menus: { main: { weight: 10 } }`).
  3. Validate the YAML/TOML indentation so each menu entry is a map under its menu name.

Example fix

# before (page front matter)
menus:
  - name: Home
    weight: 1
# after
menus:
  main:
    name: Home
    weight: 1
Defensive patterns

Strategy: validation

Validate before calling

# Validate front matter menu entries before building
# menus must be a string, slice of strings, or map with known keys
menus:
  main:
    weight: 10  # numeric, not a string like "heavy"

Try / catch

// Build-time error: wraps the underlying menu-parse failure per page
// Fix the named page's front matter rather than catching at runtime
if err := site.Build(); err != nil {
    log.Fatalf("menu config error: %v", err) // message names the offending page

Prevention

When it happens

Trigger: A page front matter `menus` value that fails both cast.ToStringE and cast.ToStringSliceE and then fails hmaps.ToStringMapE — e.g. `menu: 5`, a list of maps, or a nested value inside the menu map that isn't itself a map (navigation/pagemenus.go:77-88).

Common situations: Front matter typos like `menu: [ {name: Foo} ]` (array of maps instead of a map keyed by menu name), YAML indentation errors turning a map into a scalar/list, copy-pasting site-config menu syntax (which is a list) into page front matter where a map is expected.

Related errors


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