gohugoio/hugo · error
arguments to symdiff must be slices or arrays
Error message
arguments to symdiff must be slices or arrays
What it means
Thrown by SymDiff when either s1 or s2 is neither an array nor a slice. SymDiff computes the symmetric difference by iterating both operands; each must be a positional iterable. The default branch of the per-operand switch rejects maps, strings, structs, scalars, etc.
Solutions
- Pass only slices/arrays to symdiff: `{{ symdiff $sliceA $sliceB }}`.
- Wrap a single value: `{{ symdiff (slice $x) $sliceB }}`.
- Convert a map's values to a slice first.
- Verify both operands' types before calling.
Example fix
// before
{{ symdiff $aMap $sliceB }}
// after
{{ symdiff (slice 1 2 3) $sliceB }} Defensive patterns
Strategy: type-guard
Validate before calling
func symdiffArgsValid(s1, s2 any) error {
for i, s := range []any{s1, s2} {
k := reflect.ValueOf(s).Kind()
if k != reflect.Slice && k != reflect.Array {
return fmt.Errorf("arg %d must be slice/array, got %T", i, s)
}
}
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 both symdiff operands.
- Remember the Go signature order is SymDiff(s2, s1) — both are validated.
- Wrap single values in a slice.
- Convert map values to a slice before symdiff.
When it happens
Trigger: Calling `{{ symdiff $aMap $bSlice }}`, `{{ symdiff "abc" $bSlice }}`, or `{{ symdiff 42 $b }}`. Each operand is reflect-checked; non Slice/Array falls to the default branch. Note the argument order is (s2, s1) in the Go signature but both are validated.
Common situations: Author passes a single value or map expecting element-wise diff, or a variable resolved to a non-collection. Common with data that is sometimes a slice and sometimes a scalar.
Related errors
- arguments must be slices or arrays
- arguments to complement must be slices or arrays
- can't index item of type
- can't iterate over %T
- cannot index slice/array with type
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/6aba6ea83c2934c0.
Report an issue: GitHub.
Appendix: 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 52c9bd7908)