{"record":{"id":"9da14e1c327badf7","repo":"gohugoio/hugo","slug":"invalid-dictionary-key","errorCode":null,"errorMessage":"invalid dictionary key","messagePattern":"invalid dictionary key","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/collections.go","lineNumber":188,"sourceCode":"\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 {\n\t\t\t\t\tm = make(map[string]any)\n\t\t\t\t\tdict[key] = m\n\t\t\t\t}\n\t\t\t\tdict = m\n\t\t\t}\n\t\t\tkey = v[len(v)-1]\n\t\tdefault:\n\t\t\treturn nil, errors.New(\"invalid dictionary key\")\n\t\t}\n\t\tdict[key] = values[i+1]\n\t}\n\n\treturn root, nil\n}\n\n// First returns the first limit items in list l.\nfunc (ns *Namespace) First(limit any, l any) (any, error) {\n\tif limit == nil || l == nil {\n\t\treturn nil, errors.New(\"both limit and seq must be provided\")\n\t}\n\n\tlimitv, err := cast.ToIntE(limit)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/collections.go#L170-L206","documentation":"Dictionary (collections.go:170-189) accepts keys that are either a string or a []string (the latter for nested key paths). Any other key type (int, struct, map, etc.) hits the default branch at line 187-188.","triggerScenarios":"{{ dictionary 1 \"v\" }} (int key), {{ dictionary .Page \"v\" }} (struct key), {{ dictionary .Params \"v\" }} (map key).","commonSituations":"Using a numeric ID as a key expecting coercion; passing a Page object as a key; passing a map as a key.","solutions":["Use string keys only","Cast scalars: {{ dictionary (string .ID) \"v\" }}","For nested paths use a slice of strings: {{ dictionary (slice \"a\" \"b\") \"v\" }}"],"exampleFix":"// before\n{{ dictionary 1 \"v\" }}\n// after\n{{ dictionary \"1\" \"v\" }}","handlingStrategy":"type-guard","validationCode":"{{/* cast numeric/object keys to string */}}\n{{ dictionary (string .ID) .Value }}","typeGuard":"{{/* Go-side */}}\nfunc isValidDictKey(v any) bool {\n  switch v.(type) {\n  case string, []string:\n    return true\n  }\n  return false\n}","tryCatchPattern":null,"preventionTips":["Use only string keys (or []string for nested paths)","Cast non-string keys with (string ...) first","Never use structs, maps, or numbers as keys directly"],"tags":["hugo","go-template","collections","type-mismatch"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}