{"record":{"id":"6aba6ea83c2934c0","repo":"gohugoio/hugo","slug":"arguments-to-symdiff-must-be-slices-or-arrays","errorCode":null,"errorMessage":"arguments to symdiff must be slices or arrays","messagePattern":"arguments to symdiff must be slices or arrays","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/symdiff.go","lineNumber":63,"sourceCode":"\t\t\t\tsliceElemType = sliceType.Elem()\n\t\t\t\tslice = reflect.MakeSlice(sliceType, 0, 0)\n\t\t\t}\n\n\t\t\tfor i := range v.Len() {\n\t\t\t\tev, _ := hreflect.Indirect(v.Index(i))\n\t\t\t\tkey := normalize(ev)\n\n\t\t\t\t// Append if the key is not in their intersection.\n\t\t\t\tif ids1[key] != ids2[key] {\n\t\t\t\t\tv, err := convertValue(ev, sliceElemType)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, fmt.Errorf(\"symdiff: failed to convert value: %w\", err)\n\t\t\t\t\t}\n\t\t\t\t\tslice = reflect.Append(slice, v)\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"arguments to symdiff must be slices or arrays\")\n\t\t}\n\t}\n\n\treturn slice.Interface(), nil\n}\n","sourceCodeStart":45,"sourceCodeEnd":69,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/symdiff.go#L45-L69","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n{{ symdiff $aMap $sliceB }}\n// after\n{{ symdiff (slice 1 2 3) $sliceB }}","handlingStrategy":"type-guard","validationCode":"func symdiffArgsValid(s1, s2 any) error {\n    for i, s := range []any{s1, s2} {\n        k := reflect.ValueOf(s).Kind()\n        if k != reflect.Slice && k != reflect.Array {\n            return fmt.Errorf(\"arg %d must be slice/array, got %T\", i, s)\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 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."],"tags":["go","hugo","template","collections","symdiff","type-error"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}