{"record":{"id":"270db04a4d614024","repo":"gohugoio/hugo","slug":"len-of-nil-pointer","errorCode":null,"errorMessage":"len of nil pointer","messagePattern":"len of nil pointer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/internal/go_templates/texttemplate/funcs.go","lineNumber":295,"sourceCode":"\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\")\n\t}\n\tswitch item.Kind() {\n\tcase reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:\n\t\treturn item.Len(), nil\n\t}\n\treturn 0, fmt.Errorf(\"len of type %s\", item.Type())\n}\n\n// Function invocation\n\nfunc emptyCall(fn reflect.Value, args ...reflect.Value) reflect.Value {\n\tpanic(\"unreachable\") // implemented as a special case in evalCall\n}\n\n// call returns the result of evaluating the first argument as a function.\n// The function must return 1 result, or 2 results, the second of which is an error.\nfunc call(name string, fn reflect.Value, args ...reflect.Value) (reflect.Value, error) {\n\tfn = indirectInterface(fn)","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/internal/go_templates/texttemplate/funcs.go#L277-L313","documentation":"Raised by the `len` template function when its argument, after `indirect`, is a nil pointer (funcs.go:293-295). `len` cannot measure something that does not exist; a nil `*[]T`/`*string`/`*map` has no length.","triggerScenarios":"`{{len .Ptr}}` where `.Ptr` is a nil pointer to a slice/string/map/chan/array; optional fields typed as pointers that were never set.","commonSituations":"Optional front matter or struct fields exposed as pointers; JSON unmarshaling that leaves absent fields nil; migrations from value types to pointer types.","solutions":["Guard with `{{with .Ptr}}{{len .}}{{else}}0{{end}}`.","Change the field to a value type (`[]T` instead of `*[]T`) or initialize it.","Provide a non-nil default in the data layer."],"exampleFix":"// before\n{{len .Items}}   // .Items is *[]string, nil\n\n// after\n{{with .Items}}{{len .}}{{else}}0{{end}}","handlingStrategy":"validation","validationCode":"// Guard optional pointer fields:\n//   {{with .Ptr}}{{len .}}{{else}}0{{end}}","typeGuard":"func nonNilPointerOrZero(v interface{}) int {\n    rv := reflect.ValueOf(v)\n    if !rv.IsValid() { return 0 }\n    if rv.Kind() == reflect.Ptr && rv.IsNil() { return 0 }\n    if rv.Kind() == reflect.Ptr { rv = rv.Elem() }\n    switch rv.Kind() {\n    case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:\n        return rv.Len()\n    }\n    return 0\n}","tryCatchPattern":null,"preventionTips":["Initialize pointer fields, or change to value types.","Wrap len in {{with}} for optional pointer fields.","Provide non-nil defaults in the data layer."],"tags":["template","len","nil-pointer","text-template"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}