gohugoio/hugo · error
arguments to symdiff must be slices or arrays
Error message
arguments to symdiff must be slices or arrays
What it means
`collections.SymDiff` reflects over both arguments and requires each to be a slice or array (tpl/collections/symdiff.go:41-63). Any other kind — string, map, number, nil, a single page — hits the default branch and fails, because symmetric difference is only defined over element collections.
Source
Thrown at tpl/collections/symdiff.go:63
sliceElemType = sliceType.Elem()
slice = reflect.MakeSlice(sliceType, 0, 0)
}
for i := range v.Len() {
ev, _ := hreflect.Indirect(v.Index(i))
key := normalize(ev)
// Append if the key is not in their intersection.
if ids1[key] != ids2[key] {
v, err := convertValue(ev, sliceElemType)
if err != nil {
return nil, fmt.Errorf("symdiff: failed to convert value: %w", err)
}
slice = reflect.Append(slice, v)
}
}
default:
return nil, fmt.Errorf("arguments to symdiff must be slices or arrays")
}
}
return slice.Interface(), nil
}
View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Ensure both arguments are lists — in front matter use `tags: [a, b]` not `tags: a`.
- Guard nil/missing params: `{{ with .Params.tags }}{{ . | symdiff $other }}{{ end }}` or `default (slice)`.
- Wrap single values in a slice with `slice $v` if you genuinely have one element.
- For maps, diff their keys/values explicitly (e.g. via `keys`) — symdiff does not operate on maps.
Example fix
<!-- before: param may be a string or nil -->
{{ $d := .Params.tags | symdiff $other }}
<!-- after -->
{{ $tags := .Params.tags | default (slice) }}
{{ $d := $tags | symdiff $other }} Defensive patterns
Strategy: type-guard
Type guard
{{ if and (reflect.IsSlice $a) (reflect.IsSlice $b) }}
{{ $diff := collections.SymDiff $a $b }}
{{ else }}
{{ errorf "symdiff arguments must be slices, got %T and %T" $a $b }}
{{ end }} Prevention
- Check both arguments with reflect.IsSlice before calling symdiff
- Watch for `nil` from a missing param or `where` result — guard with `default (slice)`
- Don't pass maps or single scalars; wrap scalars in `slice x` if needed
When it happens
Trigger: Calling `{{ $x | symdiff $y }}` where either argument is not a slice/array: a map from `dict`, a plain string, an integer, a nil/missing `.Params` value, or a single Page object instead of a page collection.
Common situations: Passing `.Params.tags` when the front matter defines it as a single string instead of a list; passing a `dict` expecting map diffing; a variable that is nil because the param is unset on some pages; forgetting that `first 1 .Pages` returns a slice but `.Site.GetPage` returns a single page.
Related errors
- can't iterate over %T
- invalid dictionary key
- grouping not supported for type %T %T
- symdiff: failed to convert value: %w
- errWrongArgStructure
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/6aba6ea83c2934c0.json.
Report an issue: GitHub ↗.