gohugoio/hugo · error

union does not support slices or arrays of uncomparable…

Error message

union does not support slices or arrays of uncomparable types

What it means

Thrown by Union when an element type of the input slices is not Comparable (line 671). Union deduplicates using a map keyed by element values, which requires element types to be comparable (no slices, maps, or funcs as elements). The check runs per element of l1.

Solutions

  1. Flatten or project to a slice of comparable scalars (strings/ints) before union, e.g. extract a key field per element into []string.
  2. Use a custom dedup via scratch/range if you need to union complex elements.
  3. Confirm element types are comparable (strings, numbers, pointers, comparable structs) before calling union.

Example fix

// before
{{ union $sliceOfMapsA $sliceOfMapsB }}
// after
{{ $keys := slice }}{{ range $sliceOfMapsA }}{{ $keys = $keys | append .id }}{{ end }}
{{ range $sliceOfMapsB }}{{ $keys = $keys | append .id }}{{ end }}
{{ uniq $keys }}
Defensive patterns

Strategy: type-guard

Validate before calling

{{/* project to comparable scalars before union */}}
{{ $keys := slice }}{{ range $a }}{{ $keys = $keys | append .id }}{{ end }}
{{ range $b }}{{ $keys = $keys | append .id }}{{ end }}
{{ uniq $keys }}

Type guard

// In Go:
// func elemComparable(v any) bool {
//   if v == nil { return false }
//   rv := reflect.ValueOf(v)
//   if rv.Kind() != reflect.Slice && rv.Kind() != reflect.Array { return false }
//   return rv.Type().Elem().Comparable()
// }

Prevention

When it happens

Trigger: Calling {{ union $a $b }} where $a/$b are [][]int, []map[string]string, or contain func/interface-of-uncomparable values; piping slices-of-slices into union.

Common situations: Trying to union nested data structures; refactoring a flat string slice into a slice of structs with unexported fields (structs with unexported fields are not comparable via ==, though they are via reflect Comparable in some cases); data model changes introducing slices-of-maps.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/c8aff4eb1418b4f0. Report an issue: GitHub.

Appendix: source

Thrown at tpl/collections/collections.go:672

		case reflect.Array, reflect.Slice:
			ins = &intersector{r: reflect.MakeSlice(l1v.Type(), 0, 0), seen: make(map[any]bool)}

			if l1v.Type() != l2v.Type() &&
				l1v.Type().Elem().Kind() != reflect.Interface &&
				l2v.Type().Elem().Kind() != reflect.Interface {
				return ins.r.Interface(), nil
			}

			var (
				l1vv  reflect.Value
				isNil bool
			)

			for i := range l1v.Len() {
				l1vv, isNil = hreflect.Indirect(l1v.Index(i))

				if !l1vv.Type().Comparable() {
					return []any{}, errors.New("union does not support slices or arrays of uncomparable types")
				}

				if !isNil {
					ins.appendIfNotSeen(l1vv)
				}
			}

			if !l1vv.IsValid() {
				// The first slice may be empty. Pick the first value of the second
				// to use as a prototype.
				if l2v.Len() > 0 {
					l1vv = l2v.Index(0)
				}
			}

			for j := range l2v.Len() {
				l2vv := l2v.Index(j)
				typ := l1vv.Type()

View on GitHub (pinned to 52c9bd7908)