siyuan-note/siyuan · error

no file found

Error message

no file found

What it means

Returned by saveImportUpload (import.go:320) when the multipart form contained no entries under the 'file' field (len(form.File["file"]) < 1). The import-upload handler requires at least one uploaded file part; an empty upload — wrong field name, empty form, or a client that forgot to attach the file — is rejected before any temp directory is created.

Source

Thrown at kernel/api/import.go:320

	if len(token) != 32 {
		return false
	}
	for _, char := range token {
		if !(char >= 'a' && char <= 'z') && !(char >= 'A' && char <= 'Z') && !(char >= '0' && char <= '9') {
			return false
		}
	}
	return true
}

func saveImportUpload(c *gin.Context) (form *multipart.Form, writePath string, cleanup func(), err error) {
	form, err = c.MultipartForm()
	if err != nil {
		return
	}
	files := form.File["file"]
	if len(files) < 1 {
		err = errors.New("no file found")
		return
	}

	importDir := filepath.Join(util.TempDir, "import", gulu.Rand.String(7))
	if err = os.MkdirAll(importDir, 0755); err != nil {
		return
	}
	cleanup = func() { _ = os.RemoveAll(importDir) }
	writePath = filepath.Join(importDir, filepath.Base(files[0].Filename))
	if !gulu.File.IsSubPath(importDir, writePath) {
		err = errors.New("import path is not sub path of import dir")
		cleanup()
		return
	}

	if err = c.SaveUploadedFile(files[0], writePath); err != nil {
		cleanup()
	}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Ensure the multipart request includes a part named exactly 'file' with a real file: curl -F 'file=@archive.zip' ...
  2. Double-check the frontend FormData appends under the key 'file'.
  3. Confirm Content-Type is multipart/form-data and the body was not emptied by a proxy or size limit.

Example fix

// before
const fd = new FormData(); fd.append('upload', blob)
// after
const fd = new FormData(); fd.append('file', blob)
Defensive patterns

Strategy: validation

Validate before calling

// Ensure a 'file' part exists before submitting
if (!fileBlob) { throw new Error('select a file to import'); }
const fd = new FormData(); fd.append('file', fileBlob);

Try / catch

try { await importUpload(fd); }
catch (e) { if (/no file found/.test(e.msg)) { /* prompt user to attach file */ } else throw e; }

Prevention

When it happens

Trigger: POSTing to the import endpoint with a multipart form that omits the 'file' part, names it differently (e.g. 'data', 'upload'), or submits an empty file list. saveImportUpload at import.go:313 reads c.MultipartForm() then checks form.File["file"] at line 318.

Common situations: Frontend/form field name mismatch ('file' vs 'files' vs a custom name). Curl invocation missing -F 'file=@...'. A proxy stripping form parts. Client sending JSON instead of multipart for this endpoint.

Related errors


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