gohugoio/hugo · error
is neither a struct field, a method nor a map element of…
Error message
%s is neither a struct field, a method nor a map element of type %s
What it means
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.
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.
Example fix
// before
{{ where $numbers "Value" ">" 5 }} {{/* $numbers is []int */}}
// after
{{ range $n := $numbers }}{{ if gt $n 5 }}...{{ end }}{{ end }} Defensive patterns
Strategy: validation
Validate before calling
// Go-side: only pass collections whose element kind is Struct or Map
k := reflect.TypeOf(slice).Elem().Kind()
if k != reflect.Struct && k != reflect.Map {
// wrap scalars or use a different filter strategy
} Prevention
- 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.
When it happens
Trigger: `{{ where $numbers "Foo" ... }}` where `$numbers` is a slice of `int`; querying a field on a collection whose elements are primitives.
Common situations: 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.
Related errors
- isn't a key of map type
- can't evaluate a nil pointer of type
- error at calling a method
- is a method of type but only returns an error type
- is a method of type but requires more than parameter
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/453d8a863a77b7fc.
Report an issue: GitHub.
Appendix: source
Thrown at tpl/collections/where.go:384
obj = reflect.Indirect(obj)
switch obj.Kind() {
case reflect.Struct:
ft, ok := obj.Type().FieldByName(elemName)
if ok {
if ft.PkgPath != "" && !ft.Anonymous {
return zero, fmt.Errorf("%s is an unexported field of struct type %s", elemName, typ)
}
return obj.FieldByIndex(ft.Index), nil
}
return zero, fmt.Errorf("%s isn't a field of struct type %s", elemName, typ)
case reflect.Map:
kv := reflect.ValueOf(elemName)
if kv.Type().AssignableTo(obj.Type().Key()) {
return obj.MapIndex(kv), nil
}
return zero, fmt.Errorf("%s isn't a key of map type %s", elemName, typ)
}
return zero, fmt.Errorf("%s is neither a struct field, a method nor a map element of type %s", elemName, typ)
}
// parseWhereArgs parses the end arguments to the where function. Return a
// match value and an operator, if one is defined.
func parseWhereArgs(args ...any) (mv reflect.Value, op string, err error) {
switch len(args) {
case 1:
mv = reflect.ValueOf(args[0])
case 2:
var ok bool
if op, ok = args[0].(string); !ok {
err = errors.New("operator argument must be string type")
return
}
op = strings.TrimSpace(strings.ToLower(op))
mv = reflect.ValueOf(args[1])
default:
err = errors.New("can't evaluate the array by no match argument or more than or equal to two arguments")View on GitHub (pinned to 52c9bd7908)