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
- Convert weighted pages to plain pages first with .Pages before combining: {{ $all := union $terms.Pages .Site.RegularPages }}.
- Keep collections homogeneous: only slice WeightedPage values together, or only Page values together.
- 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
- Pass only Pages/WeightedPages collections to weighted operations (e.g. taxonomy .Pages)
- Don't mix arbitrary dicts/slices into page collections before sorting by weight
- When ranging taxonomies, use .WeightedPages accessors rather than rebuilding slices
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
- arguments to complement must be slices or arrays
- %s isn't a key of map type %s
- %s is neither a struct field, a method nor a map element of
- type %T not supported in Resource transformations
- destination must be a map, got %T
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/4f612ad86f4fd301.json.
Report an issue: GitHub ↗.