siyuan-note/siyuan · error
open form part [ ] file [ ] error
Error message
open form part [%s] file [%s] error: %s
What it means
When parsing a multipart form upload, the plugin server opens each file part via handler.Open(); if opening the uploaded file fails (disk/temp-file error), the error is wrapped with the part name and client-provided filename and returned to the caller.
Solutions
- Check the error suffix (%s) for the underlying cause and fix it (free disk space, raise ulimit -n)
- Retry the upload; transient EMFILE usually resolves after load drops
- Ensure the client sends well-formed multipart/form-data with valid file parts
Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
try { await uploadFile(form); } catch (e) { if (String(e).includes('open form part')) { await sleep(1000); await uploadFile(form); } else { throw e; } } Prevention
- Ensure the server temp directory exists, is writable, and has free space
- Raise the open-file limit for high-concurrency upload workloads
- Send standards-compliant multipart/form-data from clients
When it happens
Trigger: Uploading a file through the plugin server's multipart endpoint when the server cannot open the multipart part's underlying temp file - e.g. OS temp directory issues, too many open files, or corrupted multipart encoding.
Common situations: Server host with a full or unwritable temp directory, EMFILE (too many open files) under heavy concurrent uploads, or a client sending malformed multipart bodies.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- read form part [ ] file [ ] error
- endpoint does not accept multipart data
- multipart form is missing
- not found
- asset path [ ] does not match data path [ ]
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/4c1569dc44bd5659.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/plugin/server.go:327
} else if multipartForm != nil {
// multipart/form-data
form = &RequestForm{
Value: multipartForm.Value,
File: make(map[string][]*RequestFile),
}
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,View on GitHub (pinned to 9f775e8a12)