{"record":{"id":"bf4a6d6f1bde2f52","repo":"gohugoio/hugo","slug":"can-t-slice-item-of-type-s","errorCode":null,"errorMessage":"can't slice item of type %s","messagePattern":"can't slice item of type (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/internal/go_templates/texttemplate/funcs.go","lineNumber":264,"sourceCode":"\t}\n\tvar isNil bool\n\tif item, isNil = indirect(item); isNil {\n\t\treturn reflect.Value{}, fmt.Errorf(\"slice of nil pointer\")\n\t}\n\tif len(indexes) > 3 {\n\t\treturn reflect.Value{}, fmt.Errorf(\"too many slice indexes: %d\", len(indexes))\n\t}\n\tvar cap int\n\tswitch item.Kind() {\n\tcase reflect.String:\n\t\tif len(indexes) == 3 {\n\t\t\treturn reflect.Value{}, fmt.Errorf(\"cannot 3-index slice a string\")\n\t\t}\n\t\tcap = item.Len()\n\tcase reflect.Array, reflect.Slice:\n\t\tcap = item.Cap()\n\tdefault:\n\t\treturn reflect.Value{}, fmt.Errorf(\"can't slice item of type %s\", item.Type())\n\t}\n\t// set default values for cases item[:], item[i:].\n\tidx := [3]int{0, item.Len()}\n\tfor i, index := range indexes {\n\t\tx, err := indexArg(index, cap)\n\t\tif err != nil {\n\t\t\treturn reflect.Value{}, err\n\t\t}\n\t\tidx[i] = x\n\t}\n\t// given item[i:j], make sure i <= j.\n\tif idx[0] > idx[1] {\n\t\treturn reflect.Value{}, fmt.Errorf(\"invalid slice index: %d > %d\", idx[0], idx[1])\n\t}\n\tif len(indexes) < 3 {\n\t\treturn item.Slice(idx[0], idx[1]), nil\n\t}\n\t// given item[i:j:k], make sure i <= j <= k.","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/internal/go_templates/texttemplate/funcs.go#L246-L282","documentation":"Raised by the `slice` action when the item's reflect.Kind is not String, Array, or Slice (funcs.go:255-264). `slice` only supports the sliceable kinds; a struct, map, int, bool, chan, or func hits the default branch. The %s is the item's Go type.","triggerScenarios":"`{{slice .Map 0 1}}` on a map; `{{slice .Int 0}}` on an int; `{{slice .Time 0 4}}` on a struct like time.Time.","commonSituations":"Refactoring a field from a slice to a map or struct; passing the wrong variable to a partial that expects a slice; shortcodes that assume list input but receive a scalar.","solutions":["Print the type: `{{printf \"%T\" .X}}` to see what was actually passed.","Change the template to use the appropriate accessor (range for maps, fields for structs).","Change the data so the value is a string/array/slice before slicing."],"exampleFix":"// before\n{{slice .Meta 0 2}}   // .Meta is a map[string]string\n\n// after\n{{range $k, $v := .Meta}}{{$v}}{{end}}","handlingStrategy":"type-guard","validationCode":"// Check the kind before slicing:\n//   {{printf \"%T\" .X}}\n// Only slice String/Array/Slice; otherwise range or access fields.","typeGuard":"func isSliceable(v interface{}) bool {\n    if v == nil { return false }\n    switch reflect.TypeOf(v).Kind() {\n    case reflect.String, reflect.Slice, reflect.Array:\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Confirm the operand type with {{printf \"%T\"}} before slicing.","Don't slice maps or structs — range or field-access them.","Keep data-layer types aligned with template expectations."],"tags":["template","slice","reflection","text-template"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}