{"record":{"id":"aeb023503ba36494","repo":"siyuan-note/siyuan","slug":"read-form-part-s-file-s-error-s","errorCode":null,"errorMessage":"read form part [%s] file [%s] error: %s","messagePattern":"read form part \\[(.+?)\\] file \\[(.+?)\\] error: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/plugin/server.go","lineNumber":334,"sourceCode":"\t\tfor partName, fileHandlers := range multipartForm.File {\n\t\t\tfiles := make([]*RequestFile, len(fileHandlers))\n\t\t\tform.File[partName] = files\n\t\t\tfor i, handler := range fileHandlers {\n\t\t\t\tfiles[i] = &RequestFile{\n\t\t\t\t\tFilename: handler.Filename,\n\t\t\t\t\tHeaders:  handler.Header,\n\t\t\t\t\tSize:     handler.Size,\n\t\t\t\t}\n\t\t\t\tfile, openErr := handler.Open()\n\t\t\t\tif openErr != nil {\n\t\t\t\t\terr = fmt.Errorf(\"open form part [%s] file [%s] error: %s\", partName, handler.Filename, openErr.Error())\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcontent := make([]byte, handler.Size)\n\t\t\t\tn, readErr := file.Read(content)\n\t\t\t\tfile.Close()\n\t\t\t\tif readErr != nil {\n\t\t\t\t\terr = fmt.Errorf(\"read form part [%s] file [%s] error: %s\", partName, handler.Filename, readErr.Error())\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tfileData := content[:n]\n\t\t\t\tfiles[i].Data = &fileData\n\t\t\t}\n\t\t}\n\t} else if len(c.Request.PostForm) > 0 {\n\t\t// application/x-www-form-urlencoded\n\t\tform = &RequestForm{\n\t\t\tValue: c.Request.PostForm,\n\t\t\tFile:  nil,\n\t\t}\n\t}\n\n\tif form == nil {\n\t\t// Not a form request, read raw body data\n\t\tif rawData, readErr := c.GetRawData(); readErr != nil {\n\t\t\t// request don't have body, do nothing","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/plugin/server.go#L316-L352","documentation":"After opening a multipart file part, the plugin server reads handler.Size bytes; if file.Read returns an error the read fails, the file handle is closed, and this wrapped error (part name, filename, cause) is returned instead of the file contents.","triggerScenarios":"Reading an uploaded file part fails mid-read - typically because the client disconnected while uploading, the declared Content-Length/size disagrees with actual data, or the temp file was removed during the request.","commonSituations":"Network interruption during large uploads, mismatched multipart part sizes from custom clients, or antivirus/cleanup tools deleting temp files.","solutions":["Inspect the wrapped cause and re-upload the file","Fix the client to send accurate multipart part sizes and keep the connection open until upload completes","Use chunked/resumable uploads for large files to avoid mid-read disconnects"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if (!file || file.size === 0) throw new Error('refusing to upload empty/unknown-size file');","typeGuard":"null","tryCatchPattern":"try { await uploadFile(form); } catch (e) { if (String(e).includes('read form part')) { await sleep(1000); await uploadFile(form); } else { throw e; } }","preventionTips":["Keep the connection open until the whole multipart body is sent","Ensure declared part sizes match actual bytes sent","Use resumable/chunked uploads for large or unreliable-network transfers"],"tags":["http","multipart","file-upload","io"],"backgroundTag":"file-read-failed","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"}