gohugoio/hugo · error

invalid dictionary call

Error message

invalid dictionary call

What it means

The `dict` template function builds a map from alternating key/value arguments, so it requires an even argument count. An odd number of values means some key has no value (or vice versa), and Hugo rejects the whole call rather than guessing.

Source

Thrown at tpl/collections/collections.go:162

				str.WriteString(valStr)
			default:
				str.WriteString(valStr + d)
			}
		}

	default:
		return "", fmt.Errorf("can't iterate over %T", l)
	}

	return str.String(), nil
}

// Dictionary creates a new map from the given parameters by
// treating values as key-value pairs.  The number of values must be even.
// The keys can be string slices, which will create the needed nested structure.
func (ns *Namespace) Dictionary(values ...any) (map[string]any, error) {
	if len(values)%2 != 0 {
		return nil, errors.New("invalid dictionary call")
	}

	root := make(map[string]any)

	for i := 0; i < len(values); i += 2 {
		dict := root
		var key string
		switch v := values[i].(type) {
		case string:
			key = v
		case []string:
			for i := range len(v) - 1 {
				key = v[i]
				var m map[string]any
				v, found := dict[key]
				if found {
					m = v.(map[string]any)
				} else {

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Count the arguments — every key needs exactly one value: `{{ dict "a" 1 "b" 2 }}`.
  2. Parenthesize compound value expressions so they count as one argument: `{{ dict "title" (printf "%s — %s" .Title .Site.Title) }}`.
  3. When passing dicts to partials, build them stepwise with `merge` instead of one long argument list to keep pairs balanced.

Example fix

<!-- before -->
{{ partial "card.html" (dict "page" . "class" ) }}
<!-- after -->
{{ partial "card.html" (dict "page" . "class" "featured") }}
Defensive patterns

Strategy: validation

Validate before calling

{{/* dict requires an even number of args: key value key value */}}
{{ $d := dict "name" "hugo" "version" site.Hugo.Version }}

Prevention

When it happens

Trigger: `{{ dict "a" 1 "b" }}` — any `dict` call with an odd number of arguments, often caused by a value expression that got split or a trailing key left behind while editing.

Common situations: Forgetting to parenthesize a compound value (`dict "page" .Title .Section` passes 3 args), deleting a value but leaving its key during refactoring, or building partials' context dicts with conditionally-appended arguments that unbalance the pairs.

Related errors


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