siyuan-note/siyuan · error

Move notebook [ ] file [ ] failed

Error message

Move notebook [%s] file [%s] failed: %s

What it means

Thrown inside moveDoc (kernel/model/file.go:1936) during a CROSS-notebook move when the sub-documents folder of the moved doc cannot be renamed on disk. The code first deletes an existing destination folder (filelock.Remove) then calls filelock.Rename(absFromPath, absToPath); if the OS rename fails, the raw error is wrapped into Conf.Language(5) ("Move notebook [%s] file [%s] failed: %s") together with a logging.LogErrorf entry, and the whole MoveDocs loop aborts at that path.

Solutions

  1. Read the trailing OS error embedded in the message (e.g. 'The process cannot access the file') — it identifies permission vs lock vs disk
  2. Close other SiYuan instances and sync/backup tools touching the workspace, then retry the move
  3. Check filesystem health: write permissions on data/<toBox>/, free disk space, path length limits
  4. Inspect kernel logs for the paired 'move [path=...] in box [...] failed' line to confirm which folder failed, and verify data/<fromBox> state afterwards; re-run /api/filetree/refreshFiletree if indexes look stale
Defensive patterns

Strategy: retry

Try / catch

err := model.MoveDocs(fromPaths, toBoxID, toPath, nil)
if err != nil && strings.Contains(err.Error(), Conf.Language(5)[:14]) /* 'Move notebook' wrapper */ {
	logging.LogWarnf("cross-box folder move failed, likely transient file lock: %s", err)
	// verify data/<fromBox> state, close offenders, then retry the single failed path
}

Prevention

When it happens

Trigger: POST /api/filetree/moveDocs between two notebooks where data/<fromBox>/<docFolder> cannot be renamed to data/<toBox>/<newFolder>: destination locked by another process, permission denied, read-only or full disk, path length exceeded, or a race where another instance/sync wrote to the target between Remove and Rename.

Common situations: Two kernel instances (desktop + second workspace) opened on the same data directory; antivirus/indexer briefly locking files on Windows; data dir on a network drive (SMB/NFS) where rename is not atomic; leftover destination folder that could not be removed because a file inside was open.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/da33e4373bc471af. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/file.go:1936

	needMoveSubDocs := fromBox.Exist(fromFolder)
	if needMoveSubDocs {
		// 移动子文档文件夹

		newFolder := path.Join(toFolder, tree.ID)
		if isSameBox {
			if err = fromBox.Move(fromFolder, newFolder); err != nil {
				return
			}
		} else {
			absFromPath := filepath.Join(util.DataDir, fromBox.ID, fromFolder)
			absToPath := filepath.Join(util.DataDir, toBox.ID, newFolder)
			if filelock.IsExist(absToPath) {
				filelock.Remove(absToPath)
			}
			if err = filelock.Rename(absFromPath, absToPath); err != nil {
				msg := fmt.Sprintf(Conf.Language(5), fromBox.Name, fromPath, err)
				logging.LogErrorf("move [path=%s] in box [%s] failed: %s", fromPath, fromBox.ID, err)
				err = errors.New(msg)
				return
			}
		}
	}

	newPath = path.Join(toFolder, tree.ID+".sy")

	if isSameBox {
		if err = fromBox.Move(fromPath, newPath); err != nil {
			return
		}

		tree, err = filesys.LoadTree(fromBox.ID, newPath, luteEngine)
		if err != nil {
			return
		}

		moveTree(tree)

View on GitHub (pinned to afa823b6b4)