siyuan-note/siyuan · error
read form part [ ] file [ ] error
Error message
read form part [%s] file [%s] error: %s
What it means
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.
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
Defensive patterns
Strategy: retry
Validate before calling
if (!file || file.size === 0) throw new Error('refusing to upload empty/unknown-size file'); Type guard
null
Try / catch
try { await uploadFile(form); } catch (e) { if (String(e).includes('read form part')) { await sleep(1000); await uploadFile(form); } else { throw e; } } Prevention
- 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
When it happens
Trigger: 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.
Common situations: Network interruption during large uploads, mismatched multipart part sizes from custom clients, or antivirus/cleanup tools deleting temp files.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- open form part [ ] file [ ] error
- endpoint does not accept multipart data
- multipart form is missing
- read body failed:
- read body failed
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/aeb023503ba36494.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/server.go:334
for partName, fileHandlers := range multipartForm.File {
files := make([]*RequestFile, len(fileHandlers))
form.File[partName] = files
for i, handler := range fileHandlers {
files[i] = &RequestFile{
Filename: handler.Filename,
Headers: handler.Header,
Size: handler.Size,
}
file, openErr := handler.Open()
if openErr != nil {
err = fmt.Errorf("open form part [%s] file [%s] error: %s", partName, handler.Filename, openErr.Error())
return
}
content := make([]byte, handler.Size)
n, readErr := file.Read(content)
file.Close()
if readErr != nil {
err = fmt.Errorf("read form part [%s] file [%s] error: %s", partName, handler.Filename, readErr.Error())
return
}
fileData := content[:n]
files[i].Data = &fileData
}
}
} else if len(c.Request.PostForm) > 0 {
// application/x-www-form-urlencoded
form = &RequestForm{
Value: c.Request.PostForm,
File: nil,
}
}
if form == nil {
// Not a form request, read raw body data
if rawData, readErr := c.GetRawData(); readErr != nil {
// request don't have body, do nothingView on GitHub (pinned to 9f775e8a12)