{"id":"e615194158115f6a","repo":"gohugoio/hugo","slug":"invalid-dictionary-call","errorCode":null,"errorMessage":"invalid dictionary call","messagePattern":"invalid dictionary call","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/collections.go","lineNumber":162,"sourceCode":"\t\t\t\tstr.WriteString(valStr)\n\t\t\tdefault:\n\t\t\t\tstr.WriteString(valStr + d)\n\t\t\t}\n\t\t}\n\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"can't iterate over %T\", l)\n\t}\n\n\treturn str.String(), nil\n}\n\n// Dictionary creates a new map from the given parameters by\n// treating values as key-value pairs.  The number of values must be even.\n// The keys can be string slices, which will create the needed nested structure.\nfunc (ns *Namespace) Dictionary(values ...any) (map[string]any, error) {\n\tif len(values)%2 != 0 {\n\t\treturn nil, errors.New(\"invalid dictionary call\")\n\t}\n\n\troot := make(map[string]any)\n\n\tfor i := 0; i < len(values); i += 2 {\n\t\tdict := root\n\t\tvar key string\n\t\tswitch v := values[i].(type) {\n\t\tcase string:\n\t\t\tkey = v\n\t\tcase []string:\n\t\t\tfor i := range len(v) - 1 {\n\t\t\t\tkey = v[i]\n\t\t\t\tvar m map[string]any\n\t\t\t\tv, found := dict[key]\n\t\t\t\tif found {\n\t\t\t\t\tm = v.(map[string]any)\n\t\t\t\t} else {","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/collections/collections.go#L144-L180","documentation":"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.","triggerScenarios":"`{{ 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.","commonSituations":"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.","solutions":["Count the arguments — every key needs exactly one value: `{{ dict \"a\" 1 \"b\" 2 }}`.","Parenthesize compound value expressions so they count as one argument: `{{ dict \"title\" (printf \"%s — %s\" .Title .Site.Title) }}`.","When passing dicts to partials, build them stepwise with `merge` instead of one long argument list to keep pairs balanced."],"exampleFix":"<!-- before -->\n{{ partial \"card.html\" (dict \"page\" . \"class\" ) }}\n<!-- after -->\n{{ partial \"card.html\" (dict \"page\" . \"class\" \"featured\") }}","handlingStrategy":"validation","validationCode":"{{/* dict requires an even number of args: key value key value */}}\n{{ $d := dict \"name\" \"hugo\" \"version\" site.Hugo.Version }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure dict receives an even number of arguments — every key needs a value","When a value is conditional, supply an explicit default (`| default \"\"`) rather than omitting the pair","When building dicts dynamically with merge, verify each fragment is itself a valid dict"],"tags":["hugo","templates","dict","collections","arguments"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}