{"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/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/collections/where.go#L366-L402","documentation":"Fallback error in evaluateSubElem: the element is neither a struct nor a map (after indirection), and no method matched the key name — so there is no way to resolve a sub-element from it. Typical culprits are elements that are plain strings, numbers, or slices when the `where` key path expects addressable sub-fields.","triggerScenarios":"`where` applied to a collection of scalars, e.g. `where .Params.tags \"Name\" \"x\"` where tags is []string, or a dotted path whose intermediate segment resolves to a string/int/slice instead of a struct/map.","commonSituations":"Filtering a slice of strings as if it were a slice of objects; data files whose shape changed from list-of-maps to list-of-strings; applying `where` to `.Site.Taxonomies` values incorrectly.","solutions":["Verify the collection's element shape — `where` needs elements to be maps or structs; for scalar slices use `in` or `intersect` instead.","Fix the data so each element is a map with the expected key.","Shorten the key path so it stops at the struct/map level."],"exampleFix":"<!-- before: tags is []string -->\n{{ range where .Params.tags \"Name\" \"go\" }}\n<!-- after -->\n{{ if in .Params.tags \"go\" }} ... {{ end }}","handlingStrategy":"validation","validationCode":"{{ $first := index $c 0 }}\n{{ if or (isset $first $key) (ne (printf \"%v\" $first) \"\") }}{{/* inspect with %#v first */}}{{ end }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Confirm the accessor exists as a field, method, or map key on the element type before writing the where clause","For dotted paths like \"Params.foo\", validate each segment resolves on a sample element","Keep collections homogeneous — mixed element types make one key fail on some elements"],"tags":["hugo","templates","where","type-mismatch"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}