gohugoio/hugo · error
merge requires at least two parameters
Error message
merge requires at least two parameters
What it means
The `merge` template function combines two or more maps into one, copying the last parameter and merging preceding maps into it in reverse order. This error is thrown when fewer than two parameters are supplied, because merging is undefined without at least a source and a destination. Only maps are supported and key handling is case insensitive.
Solutions
- Add at least a second map argument, e.g. `{{ merge $defaults .Params }}` where the last parameter is the destination.
- If a map may be nil, default it: `{{ $defaults = $defaults | default dict }}` before calling merge.
- Verify that each argument resolves to a `map[string]any` or `hmaps.Params` before the call.
Example fix
// before
{{ merge .Params }}
// after
{{ merge $defaults .Params }} Defensive patterns
Strategy: validation
Validate before calling
{{ $maps := slice $a $b }}
{{ $allMaps := true }}
{{ range $maps }}{{ if not (reflectIsMap .) }}{{ $allMaps = false }}{{ end }}{{ end }}
{{ if and (ge (len $maps) 2) $allMaps }}
{{ merge $a $b }}
{{ end }} Type guard
// In Go: ensure at least two map[string]any args before calling
func isMergeableMaps(params ...any) bool {
if len(params) < 2 { return false }
for _, p := range params {
if reflect.TypeOf(p).Kind() != reflect.Map { return false }
}
return true
} Prevention
- Always provide a source and destination map to merge.
- Default optional maps with `| default dict` before merging.
- Confirm each argument is a map, not a slice or scalar.
When it happens
Trigger: Calling `collections.Merge` with zero arguments or a single argument, e.g. `{{ merge .Params }}` or `{{ merge }}`. The check at tpl/collections/merge.go:31 fails immediately when `len(params) < 2`.
Common situations: A developer writes `{{ merge .Params }}` intending to merge a page's Params with a default dict but forgets the second map. Also occurs when a template variable holding the second map is nil/unset and variadic expansion yields a single arg, or when copy-pasting from a single-arg `dict` call.
Related errors
- destination must be a map, got %T
- incompatible map types, got %T to %T
- source must be a map, got %T
- argument must be a slice
- arguments must be slices or arrays
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/369bc58273f1bac4.
Report an issue: GitHub.
Appendix: source
Thrown at tpl/collections/merge.go:32
package collections
import (
"errors"
"fmt"
"reflect"
"strings"
"github.com/gohugoio/hugo/common/hmaps"
"github.com/gohugoio/hugo/common/hreflect"
)
// Merge creates a copy of the final parameter in params and merges the preceding
// parameters into it in reverse order.
//
// Currently only maps are supported. Key handling is case insensitive.
func (ns *Namespace) Merge(params ...any) (any, error) {
if len(params) < 2 {
return nil, errors.New("merge requires at least two parameters")
}
var err error
result := params[len(params)-1]
for i := len(params) - 2; i >= 0; i-- {
result, err = ns.merge(params[i], result)
if err != nil {
return nil, err
}
}
return result, nil
}
// merge creates a copy of dst and merges src into it.
func (ns *Namespace) merge(src, dst any) (any, error) {
vdst, vsrc := reflect.ValueOf(dst), reflect.ValueOf(src)View on GitHub (pinned to 52c9bd7908)