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

  1. Ensure the multipart form is parsed exactly once per request (do not call c.MultipartForm twice or pre-read the body).
  2. Increase request body / temp limits if large uploads fail mid-stream.
  3. 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

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


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/4c1569dc44bd5659. Report an issue: GitHub.