siyuan-note/siyuan · error
open form part [%s] file [%s] error: %s
Error message
open form part [%s] file [%s] error: %s
What it means
Returned while parsing a multipart/form-data request in the plugin server: handler.Open() failed for one of the uploaded files in a form part. Wraps the underlying open error; identifies the part name and filename. The whole form-parse function returns this error and aborts request handling.
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 251596fc0d)
Solutions
- Ensure the multipart form is parsed exactly once per request (do not call c.MultipartForm twice or pre-read the body).
- Increase request body / temp limits if large uploads fail mid-stream.
- If the client aborted, surface a 4xx and retry the upload.
Example fix
// before body, _ := c.GetRawData() // consumes body form, _ := c.MultipartForm() // then Open() fails // after form, _ := c.MultipartForm() // parse once; do not pre-read raw body
Defensive patterns
Strategy: try-catch
Validate before calling
// Caller side: ensure body is multipart and not pre-consumed.
function isMultipart(req: Request): boolean {
return (req.headers.get('content-type') ?? '').toLowerCase().startsWith('multipart/form-data')
} Try / catch
// Plugin server: parse the form once, handle errors per part.
try { form, err := c.MultipartForm() }
catch (e) {
if (/open form part/i.test(String(e))) return c.String(400, 'upload part unreadable: ' + e)
throw e
} Prevention
- Parse multipart exactly once per request; do not pre-read the raw body.
- Set adequate body/temp size limits for large uploads.
- Surface client aborts as 4xx and let the client retry.
When it happens
Trigger: A plugin's request handler receives a multipart upload; for one file part, the multipart header's Open() (mime/multipart) fails — e.g. the part was already consumed, the temp file backing was removed, or the reader encountered a stream error.
Common situations: The request body was partially read/streamed before the handler; large uploads where the temp file is cleaned mid-read; client aborted mid-upload; double-parsing the same multipart form (Open can only be called once per part in some drivers).
Related errors
- read form part [%s] file [%s] error: %s
- handler did not return an object
- invalid response format: %v
- Agent capability name and description are required
- ${data.error.message}
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/4c1569dc44bd5659.
Report an issue: GitHub.