{"record":{"id":"e5b2d3165bd94d05","repo":"gohugoio/hugo","slug":"value-has-type-s-should-be-s","errorCode":null,"errorMessage":"value has type %s; should be %s","messagePattern":"value has type (.+?); should be (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/index.go","lineNumber":131,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"can't index item of type %s\", v.Type())\n\t\t}\n\t}\n\treturn v.Interface(), nil\n}\n\n// prepareArg checks if value can be used as an argument of type argType, and\n// converts an invalid value to appropriate zero if possible.\n//\n// Copied from Go stdlib src/text/template/funcs.go.\nfunc prepareArg(value reflect.Value, argType reflect.Type) (reflect.Value, error) {\n\tif !value.IsValid() {\n\t\tif !canBeNil(argType) {\n\t\t\treturn reflect.Value{}, fmt.Errorf(\"value is nil; should be of type %s\", argType)\n\t\t}\n\t\tvalue = reflect.Zero(argType)\n\t}\n\tif !value.Type().AssignableTo(argType) {\n\t\treturn reflect.Value{}, fmt.Errorf(\"value has type %s; should be %s\", value.Type(), argType)\n\t}\n\treturn value, nil\n}\n\n// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.\n//\n// Copied from Go stdlib src/text/template/exec.go.\nfunc canBeNil(typ reflect.Type) bool {\n\tswitch typ.Kind() {\n\tcase reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice:\n\t\treturn true\n\t}\n\treturn false\n}\n","sourceCodeStart":113,"sourceCodeEnd":146,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/index.go#L113-L146","documentation":"Thrown by prepareArg during map indexing when the supplied index value is valid but its reflect.Type is not AssignableTo the map's key type. This is a hard type mismatch — e.g. indexing map[int]V with a string, or map[string]V with an int. Both the actual type and expected type are named via %s.","triggerScenarios":"Calling `{{ index $intKeyedMap \"1\" }}` (string vs int key), `{{ index $stringKeyedMap 42 }}` (int vs string), or `{{ index $map $someStruct }}` where the struct isn't the key type. prepareArg's AssignableTo check fails.","commonSituations":"JSON/CSV data ingestion where keys arrive as strings but the map is int-keyed (or vice versa), template author guesses the key type, or a partial receives a key whose type differs across callers.","solutions":["Coerce the key to the map's key type: `{{ index $intMap (int $k) }}` or `{{ index $strMap (string $k) }}`.","Align the map's declaration with the keys actually used.","Standardize data ingestion so keys are consistently typed.","Inspect both types in the error message to pick the correct coercion."],"exampleFix":"// before\n{{ index $intKeyedMap \"5\" }}\n// after\n{{ index $intKeyedMap (int \"5\") }}","handlingStrategy":"type-guard","validationCode":"func assignableMapKey(mapV reflect.Value, key any) (reflect.Value, error) {\n    kv := reflect.ValueOf(key)\n    if !kv.IsValid() || !kv.Type().AssignableTo(mapV.Type().Key()) {\n        return reflect.Value{}, fmt.Errorf(\"key %T not assignable to map key %s\", key, mapV.Type().Key())\n    }\n    return kv, nil\n}","typeGuard":"func keyMatchesMap(m, key any) bool {\n    mv := reflect.ValueOf(m)\n    if mv.Kind() != reflect.Map { return false }\n    kv := reflect.ValueOf(key)\n    if !kv.IsValid() { return false }\n    return kv.Type().AssignableTo(mv.Type().Key())\n}","tryCatchPattern":null,"preventionTips":["Coerce keys to the map's declared key type before indexing.","Keep map key types consistent across data sources.","Standardize ingestion so keys are uniformly typed.","Read both types in the error to pick the right coercion."],"tags":["go","hugo","template","collections","index","map","type-error"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}