gohugoio/hugo · error

complement needs at least two arguments

Error message

complement needs at least two arguments

What it means

`collections.Complement` returns the elements of its last argument that appear in none of the earlier ones (tpl/collections/complement.go:32-35). With fewer than two arguments there is no universe/exclusion pair to compute — one collection alone has no complement — so Hugo rejects the call up front. The last-argument-is-the-universe design exists so it pipelines naturally: `{{ .Pages | complement $last4 }}`.

Source

Thrown at tpl/collections/complement.go:34

import (
	"errors"
	"fmt"
	"reflect"

	"github.com/gohugoio/hugo/common/hreflect"
)

// Complement gives the elements in the last element of ls that are not in
// any of the others.
//
// All elements of ls must be slices or arrays of comparable types.
//
// The reasoning behind this rather clumsy API is so we can do this in the templates:
//
//	{{ $c := .Pages | complement $last4 }}
func (ns *Namespace) Complement(ls ...any) (any, error) {
	if len(ls) < 2 {
		return nil, errors.New("complement needs at least two arguments")
	}

	universe := ls[len(ls)-1]
	as := ls[:len(ls)-1]

	aset, err := collectIdentities(as...)
	if err != nil {
		return nil, err
	}

	v := reflect.ValueOf(universe)
	switch v.Kind() {
	case reflect.Array, reflect.Slice:
		sl := reflect.MakeSlice(v.Type(), 0, 0)
		for i := range v.Len() {
			ev, _ := hreflect.Indirect(v.Index(i))
			if _, found := aset[normalize(ev)]; !found {
				sl = reflect.Append(sl, ev)

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Provide at least one exclusion collection plus the universe: `{{ $rest := .Pages | complement $featured }}`.
  2. If the exclusion set can be empty, still pass it as an empty slice (`default (slice)`) rather than omitting the argument.
  3. If you didn't intend a set operation, use `where` or `first` instead.

Example fix

<!-- before -->
{{ $rest := complement .Pages }}
<!-- after -->
{{ $featured := first 4 .Pages }}
{{ $rest := .Pages | complement $featured }}
Defensive patterns

Strategy: validation

Validate before calling

{{ if lt (len $sets) 2 }}
  {{ errorf "complement needs at least two collections, got %d" (len $sets) }}
{{ end }}
{{ $result := collections.Complement $exclude $universe }}

Prevention

When it happens

Trigger: Calling `{{ complement .Pages }}` with a single collection, or `{{ complement }}` with none — typically by not realizing the piped value counts as the final argument and at least one exclusion set must be passed before it.

Common situations: Misreading the docs and expecting complement of one set against the site automatically; a template refactor that drops the exclusion variable; passing the exclusion set conditionally so it's absent on some pages.

Related errors


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