gohugoio/hugo · error

type %T is not a WeightedPage

Error message

type %T is not a WeightedPage

What it means

WeightedPage.Slice implements Hugo's internal collections.Slice contract: when slicing a []any it requires every element to be a WeightedPage so it can build a homogeneous WeightedPages collection. If any element is a different type (e.g. a plain Page, a string, a map), the conversion fails with this error rather than silently producing a mixed collection.

Source

Thrown at resources/page/weighted.go:77

	return WeightedPage{Weight: weight, Page: p, owner: owner}
}

func (w WeightedPage) String() string {
	return fmt.Sprintf("WeightedPage(%d,%q)", w.Weight, w.Page.Title())
}

// Slice is for internal use.
// for the template functions. See collections.Slice.
func (p WeightedPage) Slice(in any) (any, error) {
	switch items := in.(type) {
	case WeightedPages:
		return items, nil
	case []any:
		weighted := make(WeightedPages, len(items))
		for i, v := range items {
			g, ok := v.(WeightedPage)
			if !ok {
				return nil, fmt.Errorf("type %T is not a WeightedPage", v)
			}
			weighted[i] = g
		}
		return weighted, nil
	default:
		return nil, fmt.Errorf("invalid slice type %T", items)
	}
}

// Pages returns the Pages in this weighted page set.
func (wp WeightedPages) Pages() Pages {
	pages := make(Pages, len(wp))
	for i := range wp {
		pages[i] = wp[i].Page
	}
	return pages
}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Convert weighted pages to plain pages first with .Pages before combining: {{ $all := union $terms.Pages .Site.RegularPages }}.
  2. Keep collections homogeneous: only slice WeightedPage values together, or only Page values together.
  3. If you need the underlying page from a WeightedPage, use its .Page field before slicing.

Example fix

<!-- before -->
{{ $s := slice $weighted $somePage }}
<!-- after: normalize to Pages first -->
{{ $s := slice $weighted.Page $somePage }}
Defensive patterns

Strategy: type-guard

Validate before calling

{{/* only weight-sort actual pages */}}
{{ $pages := where .Site.RegularPages "Weight" "gt" 0 }}

Type guard

// In Go extensions: p, ok := v.(page.WeightedPage); if !ok { /* skip */ }
// In templates: {{ if reflect.IsMap . | not }}...{{ end }} — pass Pages, not arbitrary slices

Prevention

When it happens

Trigger: Using the `slice` template function (or first/last/after and friends that re-slice) on a mix where the first element is a WeightedPage (typically from .Site.Taxonomies weighted lists) but later elements are plain Pages or other values, e.g. {{ $s := slice $weightedPage $regularPage }}.

Common situations: Templates that merge taxonomy term pages (WeightedPages) with regular .Pages collections; appending arbitrary values to a weighted list obtained from .Site.Taxonomies.tags; refactors that switch from .Pages to taxonomy .WeightedPages without updating downstream slice building.

Related errors


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