gohugoio/hugo · error

failed to decode sites from front matter: %w

Error message

failed to decode sites from front matter: %w

What it means

When reading a page's front matter, Hugo weak-decodes the `sites` key into the page's sites-matrix configuration (the multi-site/multilingual matrix introduced with the sites config). This error means the value under `sites` has a shape mapstructure cannot coerce into the expected Sites struct — wrong type, wrong nesting, or invalid field values.

Source

Thrown at resources/page/pagemeta/page_frontmatter.go:116

		if err := pcfg.setFromFrontMatter(frontmatter); err != nil {
			return err
		}
	}
	return pcfg.resolveContentType(ext, conf.GetConfigSection("mediaTypes").(media.Types))
}

func (pcfg *PageConfigEarly) setFromFrontMatter(frontmatter map[string]any) error {
	// Needed for case insensitive fetching of params values.
	hmaps.PrepareParams(frontmatter)
	pcfg.Frontmatter = frontmatter

	if v, found := frontmatter[pageMetaKeyMarkup]; found {
		pcfg.Content.Markup = cast.ToString(v)
	}

	if v, found := frontmatter[pageMetaKeySites]; found {
		if err := mapstructure.WeakDecode(v, &pcfg.Sites); err != nil {
			return fmt.Errorf("failed to decode sites from front matter: %w", err)
		}
	}
	return nil
}

func (p *PageConfigEarly) setCascadeEarlyValueIfNotSet(key string, value any) (done bool) {
	switch key {
	case pageMetaKeySites:
		p.Sites.SetFromParamsIfNotSet(value.(hmaps.Params))
	}

	return !p.Sites.Matrix.IsZero()
}

// Page config that needs to be set early.
type PageConfigEarly struct {
	Kind            string // The kind of page, e.g. "page", "section", "home" etc. This is usually derived from the content path.
	Path            string // The canonical path to the page, e.g. /sect/mypage. Note: Leading slash, no trailing slash, no extensions or language identifiers.

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Fix the `sites` front matter value to match the documented sites-matrix shape (a map/object, not a scalar or list).
  2. If `sites` was a custom parameter, move it under `params.sites` so it no longer collides with the reserved key.
  3. Check YAML indentation/TOML table syntax in the offending file — the wrapped decode error names the mismatched field.

Example fix

# before (front matter)
sites: "en,de"
# after
params:
  sites: "en,de"   # or use the proper sites matrix map shape
Defensive patterns

Strategy: validation

Validate before calling

# front matter: `sites` must be a list of strings
---
sites: ["en", "fr"]
---

Prevention

When it happens

Trigger: A content file whose front matter contains a `sites` key with an incompatible structure — e.g. a scalar or list where a map is expected, or nested fields that don't match the Sites schema — causing mapstructure.WeakDecode to fail during PageConfigEarly.setFromFrontMatter.

Common situations: Hand-written YAML/TOML front matter with wrong indentation making `sites` a string or list; sites config copied from site-level hugo.toml in an incompatible shape; a pre-existing custom `sites` param colliding with the newer reserved key after upgrading Hugo.

Related errors


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