{"id":"03744574c21f851c","repo":"gofiber/fiber","slug":"write-formdata-error-w","errorCode":null,"errorMessage":"write formdata error: %w","messagePattern":"write formdata error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/hooks.go","lineNumber":267,"sourceCode":"\tif err := mw.Close(); err != nil {\n\t\treturn fmt.Errorf(\"failed to close multipart writer: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// writeMultipartBody writes the form fields and files of req to mw.\nfunc writeMultipartBody(mw *multipart.Writer, req *Request) error {\n\t// Add form data.\n\tvar err error\n\tfor key, value := range req.formData.All() {\n\t\terr = mw.WriteField(utils.UnsafeString(key), utils.UnsafeString(value))\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write formdata error: %w\", err)\n\t}\n\n\t// Add files.\n\tfileBuf, ok := fileBufPool.Get().(*[]byte)\n\tif !ok {\n\t\treturn errSyncPoolBuffer\n\t}\n\n\tdefer fileBufPool.Put(fileBuf)\n\n\tfor i, f := range req.files {\n\t\tif f.name == \"\" && f.path == \"\" {\n\t\t\treturn ErrFileNoName\n\t\t}\n\n\t\t// Set the file name if not provided.\n\t\tif f.name == \"\" && f.path != \"\" {\n\t\t\tf.path = filepath.Clean(f.path)","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/client/hooks.go#L249-L285","documentation":"Returned in writeMultipartBody (client/hooks.go:267) when multipart.Writer.WriteField fails for any form-field entry. WriteField writes a part header and value into the request body writer; a failure means the underlying writer rejected the write (buffer cap, transport error, or an excessively long field that overflows the request buffer).","triggerScenarios":"Adding many or very large form fields via Request.SetFormData/SetParam and sending a filesBody request, where the accumulated form-field data exceeds the request body buffer or the body writer errors. Also possible if a field value contains data that breaks the writer.","commonSituations":"Base64-encoding a large blob into a form field; thousands of form fields; a body-stream target already closed; concurrent reuse of the Request object; a server/proxy enforcing a smaller body limit that surfaces client-side.","solutions":["Move large payloads from form fields into file parts (SetFiles) which stream through a 1MB copy buffer.","Reduce the number/size of form fields or chunk the upload.","Ensure the Request is not concurrently released while the body is being written.","Check the wrapped error for buffer-size vs. connection-failure semantics."],"exampleFix":"// before — huge value crammed into a form field\nreq.SetFormData(map[string]string{\"blob\": hugeBase64})\n\n// after — send large data as a file part instead\nreq.SetFileReader(\"blob\", \"blob.bin\", bytes.NewReader(blobBytes))","handlingStrategy":"validation","validationCode":"// Reject oversized form-field payloads before sending.\nconst maxFieldBytes = 1 << 20 // 1 MiB\nfunc fieldsFit(fields map[string]string) bool {\n    var n int\n    for k, v := range fields { n += len(k) + len(v) }\n    return n <= maxFieldBytes\n}","typeGuard":null,"tryCatchPattern":"if err := sendMultipart(req); err != nil && strings.Contains(err.Error(), \"write formdata error\") {\n    // move large fields into file parts and retry\n}","preventionTips":["Send large payloads as file parts rather than form fields.","Cap the number and size of form fields before building the request.","Keep the Request alive (no concurrent release) during body construction."],"tags":["client","multipart","formdata","upload"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}