{"record":{"id":"941c4d0fc957214d","repo":"gohugoio/hugo","slug":"invalid-slice-index-d-d","errorCode":null,"errorMessage":"invalid slice index: %d > %d","messagePattern":"invalid slice index: (.+?) > (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/internal/go_templates/texttemplate/funcs.go","lineNumber":277,"sourceCode":"\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.\n\tif idx[1] > idx[2] {\n\t\treturn reflect.Value{}, fmt.Errorf(\"invalid slice index: %d > %d\", idx[1], idx[2])\n\t}\n\treturn item.Slice3(idx[0], idx[1], idx[2]), nil\n}\n\n// Length\n\n// length returns the length of the item, with an error if it has no defined length.\nfunc length(item reflect.Value) (int, error) {\n\titem, isNil := indirect(item)\n\tif isNil {\n\t\treturn 0, fmt.Errorf(\"len of nil pointer\")","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/internal/go_templates/texttemplate/funcs.go#L259-L295","documentation":"Raised by the `slice` action for the two-index form `s[i:j]` when `i > j` (funcs.go:276-277). Like Go, the low index must not exceed the high index; otherwise the slice expression is invalid. The format prints `low > high`.","triggerScenarios":"`{{slice .S 4 2}}` where the low index exceeds the high; computed indices whose order is wrong; off-by-one where `len-1` is used as the high but a larger low.","commonSituations":"Pagination math gone wrong; templates that compute `start`/`end` from `.Paginator` and swap them; reversed bounds in a helper.","solutions":["Ensure the low index <= high index: `{{slice .S 2 4}}` not `{{slice .S 4 2}}`.","Clamp indices to `[0, len]` and sort them before slicing.","Compute bounds defensively: `{{$hi := math.Min .End (len .S)}}{{if lt .Start $hi}}{{slice .S .Start $hi}}{{end}}`."],"exampleFix":"// before\n{{slice .S (sub (len .S) 1) (sub (len .S) 3)}}\n\n// after\n{{slice .S (sub (len .S) 3) (sub (len .S) 1)}}","handlingStrategy":"validation","validationCode":"// Clamp and order bounds before slicing:\n//   {{$lo := math.Min .Start .End}}\n//   {{$hi := math.Max .Start .End}}\n//   {{slice .S $lo $hi}}","typeGuard":"func orderedBounds(lo, hi, n int) (int, int) {\n    if lo < 0 { lo = 0 }\n    if hi > n { hi = n }\n    if lo > hi { lo, hi = hi, lo }\n    return lo, hi\n}","tryCatchPattern":null,"preventionTips":["Always compute low <= high before slicing.","Clamp indices to [0, len].","Audit pagination math that derives both bounds from the same base."],"tags":["template","slice","bounds","text-template"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}