gohugoio/hugo · error

intersect does not support slices or arrays of uncomparable

Error message

intersect does not support slices or arrays of uncomparable types

What it means

`intersect` compares elements from both slices using them as map keys and `==`-style comparison, so every element type must be comparable in the Go sense. Elements that are slices, maps, or functions (e.g. []string values inside a [][]string, or map params) are uncomparable and cause this error while iterating either input.

Source

Thrown at tpl/collections/collections.go:289

func (ns *Namespace) Intersect(l1, l2 any) (any, error) {
	if l1 == nil || l2 == nil {
		return make([]any, 0), nil
	}

	var ins *intersector

	l1v := reflect.ValueOf(l1)
	l2v := reflect.ValueOf(l2)

	switch l1v.Kind() {
	case reflect.Array, reflect.Slice:
		ins = &intersector{r: reflect.MakeSlice(l1v.Type(), 0, 0), seen: make(map[any]bool)}
		switch l2v.Kind() {
		case reflect.Array, reflect.Slice:
			for i := range l1v.Len() {
				l1vv := l1v.Index(i)
				if !l1vv.Type().Comparable() {
					return make([]any, 0), errors.New("intersect does not support slices or arrays of uncomparable types")
				}

				for j := range l2v.Len() {
					l2vv := l2v.Index(j)
					if !l2vv.Type().Comparable() {
						return make([]any, 0), errors.New("intersect does not support slices or arrays of uncomparable types")
					}

					ins.handleValuePair(l1vv, l2vv)
				}
			}
			return ins.r.Interface(), nil
		default:
			return nil, errors.New("can't iterate over " + reflect.ValueOf(l2).Type().String())
		}
	default:
		return nil, errors.New("can't iterate over " + reflect.ValueOf(l1).Type().String())
	}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Intersect slices of scalars (strings, numbers) or Pages — flatten nested structures first, e.g. intersect on `.Params.tags` rather than a list of tag objects.
  2. Extract a comparable key from each element before intersecting: build a slice of IDs/strings with `range`+`append`, intersect those, then map back.
  3. For related pages, prefer Hugo's built-in `.Site.RegularPages.Related` / related-content config instead of manual intersects over complex params.

Example fix

<!-- before -->
{{ $common := intersect .Params.groups $other.Params.groups }} <!-- groups: list of maps -->
<!-- after -->
{{ $a := slice }}{{ range .Params.groups }}{{ $a = $a | append .name }}{{ end }}
{{ $b := slice }}{{ range $other.Params.groups }}{{ $b = $b | append .name }}{{ end }}
{{ $common := intersect $a $b }}
Defensive patterns

Strategy: type-guard

Validate before calling

{{/* intersect only works on slices of comparable scalars or Pages */}}
{{ $a := slice "x" "y" }}{{ $b := slice "y" "z" }}
{{ $both := intersect $a $b }}

Type guard

{{/* flatten slices-of-slices or maps to comparable keys first */}}
{{ $keys := slice }}
{{ range $m := $items }}{{ $keys = $keys | append (index $m "id") }}{{ end }}

Prevention

When it happens

Trigger: `{{ intersect $a $b }}` where either slice contains slice/map elements — e.g. intersecting `.Params.tagGroups` (a list of lists from YAML) or slices of dicts built with `slice (dict ...) (dict ...)`.

Common situations: Front-matter params that are nested lists/maps being fed to intersect for related-content logic, or accidentally intersecting page-param collections whose YAML values decoded as maps instead of scalars.

Related errors


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