{"record":{"id":"5bc6c49779c708f0","repo":"gohugoio/hugo","slug":"s-isn-t-a-field-of-struct-type-s","errorCode":null,"errorMessage":"%s isn't a field of struct type %s","messagePattern":"(.+?) isn't a field of struct type (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/where.go","lineNumber":376,"sourceCode":"\t}\n\n\t// elemName isn't a method so next start to check whether it is\n\t// a struct field or a map value. In both cases, it mustn't be\n\t// a nil value\n\tif isNil {\n\t\treturn zero, fmt.Errorf(\"can't evaluate a nil pointer of type %s by a struct field or map key name %s\", typ, elemName)\n\t}\n\tobj = reflect.Indirect(obj)\n\tswitch obj.Kind() {\n\tcase reflect.Struct:\n\t\tft, ok := obj.Type().FieldByName(elemName)\n\t\tif ok {\n\t\t\tif ft.PkgPath != \"\" && !ft.Anonymous {\n\t\t\t\treturn zero, fmt.Errorf(\"%s is an unexported field of struct type %s\", elemName, typ)\n\t\t\t}\n\t\t\treturn obj.FieldByIndex(ft.Index), nil\n\t\t}\n\t\treturn zero, fmt.Errorf(\"%s isn't a field of struct type %s\", elemName, typ)\n\tcase reflect.Map:\n\t\tkv := reflect.ValueOf(elemName)\n\t\tif kv.Type().AssignableTo(obj.Type().Key()) {\n\t\t\treturn obj.MapIndex(kv), nil\n\t\t}\n\t\treturn zero, fmt.Errorf(\"%s isn't a key of map type %s\", elemName, typ)\n\t}\n\treturn zero, fmt.Errorf(\"%s is neither a struct field, a method nor a map element of type %s\", elemName, typ)\n}\n\n// parseWhereArgs parses the end arguments to the where function.  Return a\n// match value and an operator, if one is defined.\nfunc parseWhereArgs(args ...any) (mv reflect.Value, op string, err error) {\n\tswitch len(args) {\n\tcase 1:\n\t\tmv = reflect.ValueOf(args[0])\n\tcase 2:\n\t\tvar ok bool","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/where.go#L358-L394","documentation":"In `evaluateSubElem` (where.go:376), when the object is a struct but `FieldByName(elemName)` returns `ok == false`, Hugo reports that the requested name is not a field of that struct type. This fires after the method lookup already failed, so the name matches neither a method nor a field.","triggerScenarios":"`{{ where $pages \"Auther\" ... }}` (typo of `Author`); referencing a field that exists on a related type but not the element type; stale field name after a model rename.","commonSituations":"Typos in field names; field removed/renamed in an upgrade; querying a field present only on a subtype of a heterogeneous slice.","solutions":["Check the struct definition and correct the field name spelling/casing.","If elements have heterogeneous types, normalize them to a common struct before filtering.","After a Hugo/version upgrade, diff the relevant struct for renamed fields."],"exampleFix":"// before\n{{ where $pages \"Auther\" \"==\" \"Jane\" }}\n// after\n{{ where $pages \"Author\" \"==\" \"Jane\" }}","handlingStrategy":"validation","validationCode":"// Go-side: validate the field exists on the element type\n_, ok := reflect.TypeOf(item).FieldByName(fieldName)\nif !ok { /* log and fix template */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cross-check field names against the struct definition.","After model renames, grep templates for old field names.","Use a typed data model and let the IDE/compiler catch drift in Go."],"tags":["hugo","go-templates","where","reflection","struct","typo"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}