{"record":{"id":"ad8e1f4bf378d19e","repo":"gohugoio/hugo","slug":"value-has-type-s-should-be-s-ad8e1f","errorCode":null,"errorMessage":"value has type %s; should be %s","messagePattern":"value has type (.+?); should be (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/internal/go_templates/texttemplate/funcs.go","lineNumber":161,"sourceCode":"}\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.\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 value, nil\n\t}\n\tif intLike(value.Kind()) && intLike(argType.Kind()) && value.Type().ConvertibleTo(argType) {\n\t\tvalue = value.Convert(argType)\n\t\treturn value, nil\n\t}\n\treturn reflect.Value{}, fmt.Errorf(\"value has type %s; should be %s\", value.Type(), argType)\n}\n\nfunc intLike(typ reflect.Kind) bool {\n\tswitch typ {\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn true\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn true\n\t}\n\treturn false\n}\n\n// indexArg checks if a reflect.Value can be used as an index, and converts it to int if possible.\nfunc indexArg(index reflect.Value, cap int) (int, error) {\n\tvar x int64\n\tswitch index.Kind() {\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\tx = index.Int()","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/internal/go_templates/texttemplate/funcs.go#L143-L179","documentation":"Returned by prepareArg when the argument value is valid but not assignable to the target parameter type and not an int-like convertible value. This is the general type-mismatch path during argument coercion (func calls, map key indexing, the call builtin). The first %s is the value's actual type; the second %s is the expected type.","triggerScenarios":"Passing a string where an int is expected (or vice versa) to a typed template func/method; indexing a map whose key type doesn't match the provided key; calling via the call builtin with mismatched arg types.","commonSituations":"FuncMap func with a concrete param type receiving a differently-typed template value; map key typed as int but template passes a string from URL params; refactoring a struct field's type without updating templates.","solutions":["Align the template-supplied value's type with the func/map parameter type.","Widen the func parameter to interface{} and convert inside, returning an error on mismatch.","Convert the value in the template via a helper func before passing it.","Add type assertions/conversions in the data preparation layer."],"exampleFix":"// before\n// func: func(n int) string ; data gives .Count as string\n{{ inc .Count }} // type mismatch\n\n// after\n// func: func(v any) (string, error) that parses/converts\n{{ inc .Count }}\n// or ensure .Count is int in the data model before render","handlingStrategy":"type-guard","validationCode":"func coerce(v any, t reflect.Type) (any, error) {\n    rv := reflect.ValueOf(v)\n    if !rv.IsValid() { return nil, fmt.Errorf(\"nil value\") }\n    if !rv.Type().AssignableTo(t) {\n        return nil, fmt.Errorf(\"%T not assignable to %s\", v, t)\n    }\n    return v, nil\n}","typeGuard":"func matchesType(v any, t reflect.Type) bool {\n    rv := reflect.ValueOf(v)\n    return rv.IsValid() && rv.Type().AssignableTo(t)\n}","tryCatchPattern":"if err := t.Execute(w, data); err != nil {\n    if strings.Contains(err.Error(), \"value has type\") {\n        // normalize data types (e.g. strconv) and retry\n        data = normalizeTypes(data)\n        err = t.Execute(w, data)\n    }\n}","preventionTips":["Align template data types with func parameter types.","Use interface{} params and convert inside the func.","Unit-test funcs against the exact types templates supply."],"tags":["go","text-template","funcs","reflect","type-mismatch"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}