{"id":"22cd985fdcf2e7ec","repo":"gin-gonic/gin","slug":"unknown-type","errorCode":null,"errorMessage":"unknown type","messagePattern":"unknown type","errorType":"validation","errorClass":"errUnknownType","httpStatus":400,"severity":"error","filePath":"binding/form_mapping.go","lineNumber":23,"sourceCode":"package binding\n\nimport (\n\t\"encoding\"\n\t\"errors\"\n\t\"fmt\"\n\t\"maps\"\n\t\"mime/multipart\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin/codec/json\"\n\t\"github.com/gin-gonic/gin/internal/bytesconv\"\n)\n\nvar (\n\terrUnknownType = errors.New(\"unknown type\")\n\n\t// ErrConvertMapStringSlice can not convert to map[string][]string\n\tErrConvertMapStringSlice = errors.New(\"can not convert to map slices of strings\")\n\n\t// ErrConvertToMapString can not convert to map[string]string\n\tErrConvertToMapString = errors.New(\"can not convert to map of strings\")\n)\n\nfunc mapURI(ptr any, m map[string][]string) error {\n\treturn mapFormByTag(ptr, m, \"uri\")\n}\n\nfunc mapForm(ptr any, form map[string][]string) error {\n\treturn mapFormByTag(ptr, form, \"form\")\n}\n\nfunc MapFormWithTag(ptr any, form map[string][]string, tag string) error {\n\treturn mapFormByTag(ptr, form, tag)","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/gin-gonic/gin/blob/34dac209ffb6ef85cc78c5d217bbb7ad001d68fd/binding/form_mapping.go#L5-L41","documentation":"Returned by setWithProperType's default branch (binding/form_mapping.go:385) when Gin's reflection-driven form/URI binder encounters a struct field whose reflect.Kind it cannot handle. The package declares this sentinel only for genuinely unsupported scalar kinds (complex64/128, chan, func, unsafe.Pointer, interface) since the explicit switch covers int/uint/bool/float/string/struct(time,multipart.FileHeader)/map/ptr.","triggerScenarios":"Calling c.ShouldBindWith / c.ShouldBindUri / c.ShouldBindQuery on a struct that has a field of kind complex64, complex128, chan, func, interface, or unsafe.Pointer, with a matching form/uri/query key present in the request.","commonSituations":"Defining a request DTO with a func field or chan field by mistake; embedding an interface-typed field expecting Gin to deserialize it; copying a domain model that contains non-POD fields into a binding struct.","solutions":["Inspect the struct: find fields typed complex*, chan, func, interface, or unsafe.Pointer and remove them from the binding DTO (or mark them with the tag `form:\"-\"` / `uri:\"-\"`).","Move non-bindable fields out of the request struct into a separate domain type populated after binding.","If you need an interface field, wrap it in a concrete type that implements encoding.TextUnmarshaler / binding.BindUnmarshaler so trySetCustom handles it before the default branch."],"exampleFix":"// before\ntype Req struct {\n    Handler func()  `form:\"handler\"`\n    Value   complex128 `form:\"value\"`\n}\n// after\ntype Req struct {\n    Value string `form:\"value\"`\n}","handlingStrategy":"validation","validationCode":"func isBindableStruct(t reflect.Type) error {\n    for i := 0; i < t.NumField(); i++ {\n        f := t.Field(i)\n        if f.Tag.Get(\"form\") == \"-\" && f.Tag.Get(\"uri\") == \"-\" { continue }\n        switch f.Type.Kind() {\n        case reflect.Chan, reflect.Func, reflect.Complex64, reflect.Complex128, reflect.UnsafePointer:\n            return fmt.Errorf(\"field %s has unsupported kind %s\", f.Name, f.Type.Kind())\n        }\n    }\n    return nil\n}\n// at startup: if err := isBindableStruct(reflect.TypeOf(Req{})); err != nil { log.Fatal(err) }","typeGuard":"func isBindableKind(k reflect.Kind) bool {\n    switch k {\n    case reflect.Chan, reflect.Func, reflect.Complex64, reflect.Complex128,\n         reflect.UnsafePointer, reflect.Interface:\n        return false\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Keep request DTOs as plain structs of bindable scalar kinds (int, uint, bool, float, string, time.Time, multipart.FileHeader, maps, slices, pointers).","Mark any non-bindable field with `form:\"-\" uri:\"-\"` so the binder skips it.","Add a startup reflect-based sanity check over your binding structs in tests."],"tags":["binding","form","reflection","go"],"analyzedSha":"34dac209ffb6ef85cc78c5d217bbb7ad001d68fd","analyzedAt":"2026-08-04T21:26:18.438Z","schemaVersion":2}