gohugoio/hugo · error

unwrapPage: %T not supported

Error message

unwrapPage: %T not supported

What it means

Raised by `unwrapPage` in hugolib/page_unwrap.go:42, a helper used in page equality checks and comparisons (e.g. `.IsAncestor`, `.Eq`, `in`-style checks). It accepts a `*pageState`, a `pageWrapper`, a `types.Unwrapper`, a `page.Page`, or nil; any other type — a string, a resource, a map, a slice of pages — falls to the default case and this error reports the unsupported Go type via `%T`. Callers going through `mustUnwrapPage` turn it into a panic.

Source

Thrown at hugolib/page_unwrap.go:42

type pageWrapper interface {
	page() page.Page
}

// unwrapPage is used in equality checks and similar.
func unwrapPage(in any) (page.Page, error) {
	switch v := in.(type) {
	case *pageState:
		return v, nil
	case pageWrapper:
		return v.page(), nil
	case types.Unwrapper:
		return unwrapPage(v.Unwrapv())
	case page.Page:
		return v, nil
	case nil:
		return nil, nil
	default:
		return nil, fmt.Errorf("unwrapPage: %T not supported", in)
	}
}

func mustUnwrapPage(in any) page.Page {
	p, err := unwrapPage(in)
	if err != nil {
		panic(err)
	}

	return p
}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Find the template call in the error's stack/context and pass an actual Page object (e.g. `.Site.GetPage "/about"`) instead of a string/permalink.
  2. For menu entries, use `.Page` (with a nil check) rather than `.URL` when calling page-comparison methods.
  3. If comparing by path is what you want, compare strings directly (`eq $p.RelPermalink $other`) instead of using page equality helpers.

Example fix

{{/* before */}}
{{ if .IsAncestor .Site.Home.RelPermalink }}...{{ end }}

{{/* after */}}
{{ if .IsAncestor .Site.Home }}...{{ end }}
Defensive patterns

Strategy: type-guard

Type guard

func asPage(v any) (page.Page, bool) {
    p, ok := v.(page.Page)
    return p, ok
}
// in templates: {{ if eq (printf "%T" .) "*hugolib.pageState" }} — or better: {{ with .Page }}...{{ end }}

Prevention

When it happens

Trigger: Templates passing a non-Page value where a Page is expected: e.g. `{{ if $p.Eq .Site.Home.Permalink }}` (a string), `.IsAncestor .Sections` (a slice), or passing a Resource/partial result into page-comparison functions.

Common situations: Template code comparing a page against a path or permalink string instead of the page object; iterating a menu and passing `.URL` instead of `.Page`; custom partials that lose the page type by converting it; theme incompatibilities after Hugo type changes.

Related errors


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