{"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":"validation","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/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/collections/symdiff.go#L45-L69","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"<!-- before: param may be a string or nil -->\n{{ $d := .Params.tags | symdiff $other }}\n<!-- after -->\n{{ $tags := .Params.tags | default (slice) }}\n{{ $d := $tags | symdiff $other }}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"{{ if and (reflect.IsSlice $a) (reflect.IsSlice $b) }}\n  {{ $diff := collections.SymDiff $a $b }}\n{{ else }}\n  {{ errorf \"symdiff arguments must be slices, got %T and %T\" $a $b }}\n{{ end }}","tryCatchPattern":null,"preventionTips":["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"],"tags":["hugo","templates","collections","type-error"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}