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 bool

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Fix the field name spelling/casing to match an exported field or method.
  2. For front-matter values, prefix with `Params.`, e.g. `where .Site.RegularPages "Params.author" "jane"`.
  3. 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

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


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/5bc6c49779c708f0.json. Report an issue: GitHub ↗.