{"record":{"id":"da13b456b90ac2b0","repo":"siyuan-note/siyuan","slug":"unsupported-multipart-field-s","errorCode":null,"errorMessage":"unsupported multipart field: %s","messagePattern":"unsupported multipart field: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/multipart.go","lineNumber":98,"sourceCode":"\t\t\t\tvalue.Field(i).Set(reflect.ValueOf(files[0]))\n\t\t\t}\n\t\tcase reflect.TypeFor[string](), reflect.TypeFor[*string]():\n\t\t\tvalues := form.Value[name]\n\t\t\tif len(values) == 0 {\n\t\t\t\tif !optional {\n\t\t\t\t\treturn request, fmt.Errorf(\"Field [%s] is required\", name)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif field.Type.Kind() == reflect.Pointer {\n\t\t\t\ttext := reflect.New(field.Type.Elem())\n\t\t\t\ttext.Elem().SetString(values[0])\n\t\t\t\tvalue.Field(i).Set(text)\n\t\t\t} else {\n\t\t\t\tvalue.Field(i).SetString(values[0])\n\t\t\t}\n\t\tdefault:\n\t\t\treturn request, fmt.Errorf(\"unsupported multipart field: %s\", name)\n\t\t}\n\t}\n\treturn\n}\n","sourceCodeStart":80,"sourceCodeEnd":103,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/multipart.go#L80-L103","documentation":"DecodeMultipart only knows how to map file parts (*multipart.FileHeader / slice) and string / *string parts; any struct field of another type hits the default branch and fails with this error. The request struct's field types must be restricted to the supported set, since multipart form values are strings and file headers only.","triggerScenarios":"A multipart endpoint's request struct contains a field of an unsupported type, e.g. int, bool, []string, time.Time, or a custom struct, carrying an `api` form tag.","commonSituations":"Developer adds a numeric or boolean convenience field to an existing multipart request struct without realizing only strings/files are supported; code generation produced a typed field from a schema that assumed JSON bodies.","solutions":["Change the field type to string (or *string) in the request struct and convert/parse it in the business handler.","Remove the field from the struct if it is not actually part of the form.","Handle the raw form via the MultipartFields request type if you need arbitrary access to values."],"exampleFix":"// before\ntype req struct {\n  Count int `api:\"count\"`\n}\n// after\ntype req struct {\n  Count string `api:\"count\"` // strconv.Atoi in handler\n}","handlingStrategy":"type-guard","validationCode":"// Go: ensure multipart struct fields are only string, *string, *multipart.FileHeader, or []*multipart.FileHeader\nfor _, f := range reflect.TypeOf(Req{}).Fields() { _ = f }","typeGuard":"func multipartFieldTypeOk(t reflect.Type) bool { return t == reflect.TypeFor[string]() || t == reflect.TypeFor[*string]() || t == reflect.TypeFor[*multipart.FileHeader]() || t == reflect.TypeFor[[]*multipart.FileHeader]() }","tryCatchPattern":"if err := decode(form); err != nil && strings.Contains(err.Error(), \"unsupported multipart field\") { log.Fatalf(\"unsupported field type in request struct: %v\", err) }","preventionTips":["Restrict multipart request struct fields to strings and file headers only.","Parse numbers/booleans from strings in the business handler.","Cover each multipart struct with a decode unit test."],"tags":["go","multipart","reflection"],"backgroundTag":"unsupported-dtype","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}