{"record":{"id":"000c63f4da150aba","repo":"gohugoio/hugo","slug":"arguments-must-be-slices-or-arrays","errorCode":null,"errorMessage":"arguments must be slices or arrays","messagePattern":"arguments must be slices or arrays","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/reflect_helpers.go","lineNumber":73,"sourceCode":"// collects identities from the slices in seqs into a set. Numeric values are normalized,\n// pointers unwrapped.\nfunc collectIdentities(seqs ...any) (map[any]bool, error) {\n\tseen := make(map[any]bool)\n\tfor _, seq := range seqs {\n\t\tv := reflect.ValueOf(seq)\n\t\tswitch v.Kind() {\n\t\tcase reflect.Array, reflect.Slice:\n\t\t\tfor i := range v.Len() {\n\t\t\t\tev, _ := hreflect.Indirect(v.Index(i))\n\n\t\t\t\tif !ev.Type().Comparable() {\n\t\t\t\t\treturn nil, errors.New(\"elements must be comparable\")\n\t\t\t\t}\n\n\t\t\t\tseen[normalize(ev)] = true\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"arguments must be slices or arrays\")\n\t\t}\n\t}\n\n\treturn seen, nil\n}\n\n// We have some different numeric and string types that we try to behave like\n// they were the same.\nfunc convertValue(v reflect.Value, to reflect.Type) (reflect.Value, error) {\n\tif v.Type().AssignableTo(to) {\n\t\treturn v, nil\n\t}\n\tswitch kind := to.Kind(); {\n\tcase kind == reflect.String:\n\t\treturn hreflect.ToStringValueE(v)\n\tcase hreflect.IsNumber(kind):\n\t\treturn convertNumber(v, to)\n\tdefault:","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/reflect_helpers.go#L55-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n{{ symdiff $aMap $sliceB }}\n// after\n{{ symdiff (slice 1 2 3) $sliceB }}","handlingStrategy":"type-guard","validationCode":"func allArgsSliceOrArray(args ...any) error {\n    for _, a := range args {\n        k := reflect.ValueOf(a).Kind()\n        if k != reflect.Slice && k != reflect.Array {\n            return fmt.Errorf(\"arg must be slice/array, got %T\", a)\n        }\n    }\n    return nil\n}","typeGuard":"func isSliceOrArray(v any) bool {\n    if v == nil { return false }\n    k := reflect.ValueOf(v).Kind()\n    return k == reflect.Slice || k == reflect.Array\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["go","hugo","template","collections","type-error","set-operations"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}