{"record":{"id":"5206162c1c204fa4","repo":"gohugoio/hugo","slug":"index-of-nil-pointer","errorCode":null,"errorMessage":"index of nil pointer","messagePattern":"index of nil pointer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/internal/go_templates/texttemplate/funcs.go","lineNumber":207,"sourceCode":"\t}\n\treturn int(x), nil\n}\n\n// Indexing.\n\n// index returns the result of indexing its first argument by the following\n// arguments. Thus \"index x 1 2 3\" is, in Go syntax, x[1][2][3]. Each\n// indexed item must be a map, slice, or array.\nfunc index(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) {\n\titem = indirectInterface(item)\n\tif !item.IsValid() {\n\t\treturn reflect.Value{}, fmt.Errorf(\"index of untyped nil\")\n\t}\n\tfor _, index := range indexes {\n\t\tindex = indirectInterface(index)\n\t\tvar isNil bool\n\t\tif item, isNil = indirect(item); isNil {\n\t\t\treturn reflect.Value{}, fmt.Errorf(\"index of nil pointer\")\n\t\t}\n\t\tswitch item.Kind() {\n\t\tcase reflect.Array, reflect.Slice, reflect.String:\n\t\t\tx, err := indexArg(index, item.Len())\n\t\t\tif err != nil {\n\t\t\t\treturn reflect.Value{}, err\n\t\t\t}\n\t\t\titem = item.Index(x)\n\t\tcase reflect.Map:\n\t\t\tindex, err := prepareArg(index, item.Type().Key())\n\t\t\tif err != nil {\n\t\t\t\treturn reflect.Value{}, err\n\t\t\t}\n\t\t\tif x := item.MapIndex(index); x.IsValid() {\n\t\t\t\titem = x\n\t\t\t} else {\n\t\t\t\titem = reflect.Zero(item.Type().Elem())\n\t\t\t}","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/internal/go_templates/texttemplate/funcs.go#L189-L225","documentation":"Returned by the index builtin when, after indirect dereferencing, the item is a nil pointer (isNil == true). Indexing through a nil pointer is invalid because the underlying value does not exist. This occurs when the collection is a typed nil pointer to a slice/map/array.","triggerScenarios":"Calling {{index .Ptr 0}} where .Ptr is a *[]T or *map[K]V that is nil; a struct field typed as a pointer to a collection that was never allocated.","commonSituations":"Optional pointer-to-slice fields left nil in the data model; nested structs where a parent pointer is nil; JSON unmarshaling that leaves pointer fields nil for absent keys.","solutions":["Guard with {{if .Ptr}}{{index .Ptr 0}}{{end}} or use {{with .Ptr}}{{index . 0}}{{end}}.","Initialize pointer-to-collection fields to non-nil in the data layer (allocate the slice/map).","Prefer non-pointer collection fields in the data model when nil is not meaningful.","Return a zero value via a helper func when the pointer is nil."],"exampleFix":"// before\n{{index .Items 0}} // .Items is *[]T and nil -> error\n\n// after\n{{with .Items}}{{index . 0}}{{end}}\n// or allocate: data.Items = &[]T{} before render","handlingStrategy":"validation","validationCode":"// avoid pointer-to-collection fields, or allocate them\ntype Data struct{ Items *[]any }\nfunc init() { d.Items = &[]any{} } // never nil","typeGuard":"func isNonNilPointerToCollection(v any) bool {\n    rv := reflect.ValueOf(v)\n    if rv.Kind() != reflect.Pointer || rv.IsNil() { return false }\n    switch rv.Type().Elem().Kind() {\n    case reflect.Slice, reflect.Array, reflect.Map: return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Prefer non-pointer collection fields in data models.","Allocate pointer-to-collection fields before render.","Use {{with .Ptr}}{{index . 0}}{{end}} to guard nil pointers."],"tags":["go","text-template","index","nil-pointer","reflect"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}