gohugoio/hugo · error
%s isn't a field of struct type %s
Error message
%s isn't a field of struct type %s
What it means
The element being filtered is a struct, and after failing to find a matching method, reflect's FieldByName found no field with the given name. Hugo reports the exact struct type so the author can see what they were actually filtering, since `where` requires the key to resolve on every element it inspects.
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 8a468df065)
Solutions
- Fix the field name spelling/casing to match an exported field or method.
- For front-matter values, prefix with `Params.`, e.g. `where .Site.RegularPages "Params.author" "jane"`.
- Print one element's structure with `{{ printf "%#v" (index $c 0) }}` or `jsonify` to see available fields.
Example fix
<!-- before -->
{{ range where .Site.RegularPages "author" "jane" }}
<!-- after -->
{{ range where .Site.RegularPages "Params.author" "jane" }} Defensive patterns
Strategy: validation
Validate before calling
{{ $first := index $pages 0 }}
{{ if isset $first "Draft" }}{{ $r = where $pages "Draft" false }}{{ end }} Prevention
- Verify the field name exists on the element type (case-sensitive, exported) before using it in where
- Use printf "%#v" on one element during development to inspect available fields
- Prefer documented Page fields/methods over guessed names
When it happens
Trigger: `where` over a slice of structs (e.g. Pages) with a key that is neither a field nor method of that struct: `where .Site.RegularPages "Sction" "blog"` (typo), or using a Params key directly without the `Params.` prefix on a struct-typed element.
Common situations: Typos in field names; expecting front-matter params to be top-level fields (`where .Pages "author" x` instead of `"Params.author"`); Hugo version upgrades that renamed or removed struct fields.
Related errors
- can't iterate over %T
- invalid intersect values
- no such operator
- can't evaluate an invalid value
- %s is an unexported method of type %s
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/5bc6c49779c708f0.json.
Report an issue: GitHub ↗.