{"record":{"id":"dbec3348886de1bf","repo":"gohugoio/hugo","slug":"cannot-append-slice-of-s-to-slice-of-s","errorCode":null,"errorMessage":"cannot append slice of %s to slice of %s","messagePattern":"cannot append slice of (.+?) to slice of (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/collections/append.go","lineNumber":58,"sourceCode":"\t\t\ttov = c\n\t\t}\n\n\t\tif tov.Kind() != reflect.Slice {\n\t\t\treturn nil, fmt.Errorf(\"expected a slice, got %T\", to)\n\t\t}\n\n\t\ttot = tov.Type().Elem()\n\t\tif tot.Kind() == reflect.Slice {\n\t\t\ttotvt := tot.Elem()\n\t\t\tfromvs := make([]reflect.Value, len(from))\n\t\t\tfor i, f := range from {\n\t\t\t\tfromv := reflect.ValueOf(f)\n\t\t\t\tfromt := fromv.Type()\n\t\t\t\tif fromt.Kind() == reflect.Slice {\n\t\t\t\t\tfromt = fromt.Elem()\n\t\t\t\t}\n\t\t\t\tif totvt != fromt {\n\t\t\t\t\treturn nil, fmt.Errorf(\"cannot append slice of %s to slice of %s\", fromt, totvt)\n\t\t\t\t} else {\n\t\t\t\t\tfromvs[i] = fromv\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn reflect.Append(tov, fromvs...).Interface(), nil\n\n\t\t}\n\n\t\ttoIsNil = tov.Len() == 0\n\n\t\tif len(from) == 1 {\n\t\t\tfromv := reflect.ValueOf(from[0])\n\t\t\tif !fromv.IsValid() {\n\t\t\t\t// from[0] is nil\n\t\t\t\treturn appendToInterfaceSliceFromValues(tov, fromv)\n\t\t\t}\n\t\t\tfromt := fromv.Type()\n\t\t\tif fromt.Kind() == reflect.Slice {","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/common/collections/append.go#L40-L76","documentation":"Returned when the destination slice is a slice-of-slices (tot.Kind()==Slice) and an element being appended does not match the inner element type. Append requires homogeneous slice-of-slice contents; mismatched inner types are rejected rather than silently widening.","triggerScenarios":"Calling Append on a `[][]string` with a `[]int`, or on `[][]any` with a non-slice scalar that fails the inner-type check at append.go:57-58.","commonSituations":"Template code that mixes heterogeneous list types into a nested slice (e.g. appending a list of tags to a list-of-list-of-sections). Config-driven pipelines that build matrix dimensions from mismatched frontmatter fields.","solutions":["Inspect both type names printed in the message (from-type, to-type) and align them.","Convert the source slice elements to match the destination inner element type before appending.","If heterogeneous data is intentional, use `[]any` as the inner type on both sides."],"exampleFix":"// before\ndst := [][]string{{\"a\"}}\ncollections.Append(dst, []int{1})\n// after\ndst := [][]any{{\"a\"}}\ncollections.Append(dst, []any{1})","handlingStrategy":"type-guard","validationCode":"func sameInnerElem(dst any, src any) bool {\n  d := reflect.TypeOf(dst); s := reflect.TypeOf(src)\n  if d == nil || s == nil { return false }\n  if d.Kind() != reflect.Slice || d.Elem().Kind() != reflect.Slice { return false }\n  if s.Kind() == reflect.Slice { s = s.Elem() }\n  return d.Elem().Elem() == s\n}","typeGuard":"func canAppendNested(dst, src any) bool { return sameInnerElem(dst, src) }","tryCatchPattern":null,"preventionTips":["Use a single concrete nested-slice type throughout a pipeline.","Add a helper that flattens heterogeneous inputs to []any before nested appends."],"tags":["collections","append","slice","type-mismatch","reflection"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}