gohugoio/hugo · error
isn't a field of struct type
Error message
%s isn't a field of struct type %s
What it means
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.
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.
Example fix
// before
{{ where $pages "Auther" "==" "Jane" }}
// after
{{ where $pages "Author" "==" "Jane" }} Defensive patterns
Strategy: validation
Validate before calling
// Go-side: validate the field exists on the element type
_, ok := reflect.TypeOf(item).FieldByName(fieldName)
if !ok { /* log and fix template */ } Prevention
- 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.
When it happens
Trigger: `{{ 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.
Common situations: Typos in field names; field removed/renamed in an upgrade; querying a field present only on a subtype of a heterogeneous slice.
Related errors
- is an unexported field of struct 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/5bc6c49779c708f0.
Report an issue: GitHub.
Appendix: source
Thrown at tpl/collections/where.go:376
}
// elemName isn't a method so next start to check whether it is
// a struct field or a map value. In both cases, it mustn't be
// a nil value
if isNil {
return zero, fmt.Errorf("can't evaluate a nil pointer of type %s by a struct field or map key name %s", typ, elemName)
}
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 boolView on GitHub (pinned to 52c9bd7908)