gohugoio/hugo · error

can't evaluate the array by no match argument or more than…

Error message

can't evaluate the array by no match argument or more than or equal to two arguments

What it means

The `where` function accepts, after the collection and key, either one argument (the match value, implicit equality) or two arguments (operator string + match value). `parseWhereArgs` rejects zero trailing arguments (no match value to compare against) and three or more (too many), via the default branch at where.go:401–402.

Solutions

  1. Provide exactly one match value: `{{ where .Pages "Section" "blog" }}`.
  2. Or provide exactly one operator and one match value: `{{ where .Pages "Section" "eq" "blog" }}`.
  3. Chain multiple `where` calls for compound conditions rather than passing extra args.

Example fix

// before
{{ where .Pages "Title" }}
// after
{{ where .Pages "Title" "ne" "" }}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure 1 or 2 trailing args to where
{{ $trailing := slice $maybeOp $maybeVal }}
{{ if or (eq (len $trailing) 1) (eq (len $trailing) 2) }}
  {{ $args := prepend $trailing $key }}
  {{ where .Pages $key $trailing... }}
{{ end }}

Type guard

func validWhereTrailingArity(n int) bool {
    return n == 1 || n == 2
}

Prevention

When it happens

Trigger: Calling `{{ where .Pages "Title" }}` (missing match value) or `{{ where .Pages "Title" "eq" "x" "y" }}` (three trailing args). The message "no match argument" covers the zero-arg case; "more than or equal to two arguments" covers three or more.

Common situations: A developer omits the match value expecting a truthiness filter, or pastes extra arguments from a multi-condition template expecting AND behavior.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/a5662a04b60c87b4. Report an issue: GitHub.

Appendix: source

Thrown at tpl/collections/where.go:402

	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")
	}
	return
}

// elemResolver resolves a sub-element from a reflect.Value.
// Built once before the loop to avoid repeated type checks and reflect.ValueOf allocations.
type elemResolver func(reflect.Value) (reflect.Value, error)

// newElemResolver returns a resolver optimized for the given element type and path.
// Returns nil if optimization isn't possible, in which case the caller should
// fall back to evaluateSubElem.
func (ns *Namespace) newElemResolver(ctxv reflect.Value, elemType reflect.Type, path []string) elemResolver {
	if elemType.Kind() == reflect.Interface {
		if len(path) != 1 {
			return nil
		}
		return ns.newInterfaceMethodResolver(ctxv, elemType, path[0])
	}

View on GitHub (pinned to 52c9bd7908)