gohugoio/hugo · error
arguments must be slices or arrays
Error message
arguments must be slices or arrays
What it means
Thrown by collectIdentities (reflect_helpers.go) when any sequence passed to it is neither array nor slice. collectIdentities builds a normalized identity set for set operations; it is called by Complement (for the exclusion args) and SymDiff. The default branch rejects maps, strings, structs, scalars, etc.
Source
Thrown at tpl/collections/reflect_helpers.go:73
// collects identities from the slices in seqs into a set. Numeric values are normalized,
// pointers unwrapped.
func collectIdentities(seqs ...any) (map[any]bool, error) {
seen := make(map[any]bool)
for _, seq := range seqs {
v := reflect.ValueOf(seq)
switch v.Kind() {
case reflect.Array, reflect.Slice:
for i := range v.Len() {
ev, _ := hreflect.Indirect(v.Index(i))
if !ev.Type().Comparable() {
return nil, errors.New("elements must be comparable")
}
seen[normalize(ev)] = true
}
default:
return nil, fmt.Errorf("arguments must be slices or arrays")
}
}
return seen, nil
}
// We have some different numeric and string types that we try to behave like
// they were the same.
func convertValue(v reflect.Value, to reflect.Type) (reflect.Value, error) {
if v.Type().AssignableTo(to) {
return v, nil
}
switch kind := to.Kind(); {
case kind == reflect.String:
return hreflect.ToStringValueE(v)
case hreflect.IsNumber(kind):
return convertNumber(v, to)
default:View on GitHub (pinned to 52c9bd7908)
Solutions
- Pass only slices/arrays to Complement and SymDiff operands.
- Convert a map's keys or values to a slice before calling.
- Wrap a single value: `{{ symdiff (slice $x) $other }}`.
- Verify each operand's type at the call site.
Example fix
// before
{{ symdiff $aMap $sliceB }}
// after
{{ symdiff (slice 1 2 3) $sliceB }} Defensive patterns
Strategy: type-guard
Validate before calling
func allArgsSliceOrArray(args ...any) error {
for _, a := range args {
k := reflect.ValueOf(a).Kind()
if k != reflect.Slice && k != reflect.Array {
return fmt.Errorf("arg must be slice/array, got %T", a)
}
}
return nil
} Type guard
func isSliceOrArray(v any) bool {
if v == nil { return false }
k := reflect.ValueOf(v).Kind()
return k == reflect.Slice || k == reflect.Array
} Prevention
- Pass only slices/arrays to Complement exclusion args and SymDiff operands.
- Convert map keys/values to slices before set operations.
- Wrap single values in a slice.
- Distinguish this (auxiliary-set) error from the universe-specific Complement error.
When it happens
Trigger: Calling Complement or SymDiff with a non-slice/array among the operands — e.g. `{{ complement $aMap $universe }}` (where the map is an exclusion arg, not the universe) or `{{ symdiff $aString $other }}`. Each seq is reflect-checked; non Slice/Array hits the default branch.
Common situations: Author passes a map where a slice was expected, a single page object, or a string. Often confused with the universe-specific Complement error (625) — this one targets the auxiliary set members.
Related errors
- isset unable to use key of type %T as index
- type %T not supported
- arguments to complement must be slices or arrays
- cannot index slice/array with type %s
- can't index item of type %s
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/000c63f4da150aba.
Report an issue: GitHub.