{"record":{"id":"453d8a863a77b7fc","repo":"gohugoio/hugo","slug":"s-is-neither-a-struct-field-a-method-nor-a-map-e","errorCode":null,"errorMessage":"%s is neither a struct field, a method nor a map element of type %s","messagePattern":"(.+?) is neither a struct field, a method nor a map element of type (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/where.go","lineNumber":384,"sourceCode":"\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\n\t\tif op, ok = args[0].(string); !ok {\n\t\t\terr = errors.New(\"operator argument must be string type\")\n\t\t\treturn\n\t\t}\n\t\top = strings.TrimSpace(strings.ToLower(op))\n\t\tmv = reflect.ValueOf(args[1])\n\tdefault:\n\t\terr = errors.New(\"can't evaluate the array by no match argument or more than or equal to two arguments\")","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/where.go#L366-L402","documentation":"The fallthrough case in `evaluateSubElem` (where.go:384): the name matched no method, the value is not nil, and the object's Kind is neither `Struct` nor `Map` (e.g. it is a basic scalar, slice, array, channel, or func). Hugo reports that the name is neither a struct field, a method, nor a map element of the given type.","triggerScenarios":"`{{ where $numbers \"Foo\" ... }}` where `$numbers` is a slice of `int`; querying a field on a collection whose elements are primitives.","commonSituations":"Filtering a slice of scalars as if it were a slice of objects; a generic `[]any` whose elements are not all structs/maps; misconfigured data shape.","solutions":["Confirm the element type is actually a struct or map; if it's scalar, filter directly without a key (`{{ where $nums \">\" 5 }}` is invalid — use `range` + `if`).","Wrap scalars in structs with a `Value` field during data preparation.","Verify the collection is not a nested slice-of-slices where the inner element is itself a slice."],"exampleFix":"// before\n{{ where $numbers \"Value\" \">\" 5 }}  {{/* $numbers is []int */}}\n// after\n{{ range $n := $numbers }}{{ if gt $n 5 }}...{{ end }}{{ end }}","handlingStrategy":"validation","validationCode":"// Go-side: only pass collections whose element kind is Struct or Map\nk := reflect.TypeOf(slice).Elem().Kind()\nif k != reflect.Struct && k != reflect.Map {\n    // wrap scalars or use a different filter strategy\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Filter scalar slices with `range`+`if`, not `where` with a key.","Wrap scalars in structs (`{Value int}`) for `where` usage.","Assert element types in data-prep tests."],"tags":["hugo","go-templates","where","reflection","type-mismatch","scalar"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}