gohugoio/hugo · error

%q did not match a valid Page Kind

Error message

%q did not match a valid Page Kind

What it means

`decodePageMatcher` lowercases the `kind` given in a cascade `_target` (or other page matcher) and treats it as a glob, then checks it against `kinds.AllKindsInPages`. If no in-page kind matches the glob, Hugo returns this error. It guards against silently-inert cascades that would never apply because the kind name is wrong.

Source

Thrown at resources/page/page_matcher.go:244

		default:
			pcfg.Fields[k] = v
		}
	}
	return pcfg, pcfg.init()
}

// decodePageMatcher decodes m into v.
func (d cascadeConfigDecoder) decodePageMatcher(m any, v *PageMatcher) error {
	if err := mapstructure.WeakDecode(m, v); err != nil {
		return err
	}

	v.Kind = strings.ToLower(v.Kind)
	if v.Kind != "" {
		g, _ := hglob.GetGlob(v.Kind)
		found := slices.ContainsFunc(kinds.AllKindsInPages, g.Match)
		if !found {
			return fmt.Errorf("%q did not match a valid Page Kind", v.Kind)
		}
	}

	v.Path = filepath.ToSlash(strings.ToLower(v.Path))

	if v.Lang != "" {
		v.Sites.Matrix.Languages = append(v.Sites.Matrix.Languages, v.Lang)
		v.Sites.Matrix.Languages = hstrings.UniqueStringsReuse(v.Sites.Matrix.Languages)
	}

	return nil
}

func (v *PageMatcher) compileGlobs() error {
	var err error
	if v.Kind != "" {
		v.kindGlob, err = hglob.GetGlob(v.Kind)
		if err != nil {

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Use a valid page kind: `page`, `home`, `section`, `taxonomy`, or `term`. Kind matching is case-insensitive.
  2. If you migrated from Hugo < 0.73, replace `taxonomyTerm` with `term` and re-check any `taxonomy` targets — the meanings swapped.
  3. Don't use layout names (`single`, `list`) as kinds; those belong in layout lookups, not page matchers.
  4. Glob syntax is supported, so `{taxonomy,term}` targets both — verify your glob actually matches by building and checking the cascade takes effect.

Example fix

# before
cascade:
  - _target:
      kind: single
    banner: hero.jpg

# after
cascade:
  - _target:
      kind: page
    banner: hero.jpg
Defensive patterns

Strategy: validation

Validate before calling

// check kind against the valid set before configuring a matcher
validKinds := map[string]bool{"home": true, "page": true, "section": true, "taxonomy": true, "term": true}
if kind != "" && !validKinds[strings.ToLower(kind)] {
    return fmt.Errorf("invalid page kind %q", kind)
}

Prevention

When it happens

Trigger: A `_target: {kind: ...}` naming something that isn't a page kind — e.g. `single`, `list`, `sitemap`, `robotsTXT`, `posts`, or a typo like `sectoin`; also fires for a glob such as `t*rm` that happens to match nothing in `AllKindsInPages`.

Common situations: Confusing layout template names (`single`, `list`) with page kinds (`page`, `section`, `taxonomy`, `term`, `home`); using pre-0.73 kind names such as `taxonomyTerm`, which was renamed to `term` while the old `taxonomy` semantics shifted; assuming output-format kinds like `sitemap` are matchable.

Related errors


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