siyuan-note/siyuan · error
Move notebook [%s] file [%s] failed: %s
Error message
Move notebook [%s] file [%s] failed: %s
What it means
Thrown by the internal moveDocsByPath function during a cross-box (isSameBox=false) move, when renaming the source document's sub-document folder (filelock.Rename) from the source notebook's data directory to the destination's fails. Conf.Language(5) = 'Move notebook [%s] file [%s] failed: %s', formatted with the source box name, source path, and the OS-level rename error. This is the sub-doc folder move (not the .sy file itself), occurring when the source document has child documents stored in a folder.
Source
Thrown at kernel/model/file.go:1872
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 251596fc0d)
Solutions
- Check kernel logs for the specific OS error appended to the message (the %s at the end of Language(5)).
- If moving across filesystems, ensure both notebook data directories are on the same volume, or use copy-then-delete as a fallback.
- Close other applications that may lock the source folder (sync clients, file explorers, antivirus).
- Retry the move after a brief pause if the lock is transient.
- If the destination already has conflicting data, manually clean it up before re-attempting.
Defensive patterns
Strategy: try-catch
Try / catch
if err := model.MoveDocs(fromPaths, toBoxID, toPath, callback); err != nil {
if strings.Contains(err.Error(), conf.Conf.Language(5)[:10]) {
// Move file failed — check logs for OS-level error
logging.LogErrorf("move failed, possible lock or cross-device: %s", err)
// advise user to close locking apps or move within same volume
}
return err
} Prevention
- Ensure source and destination notebooks are on the same filesystem to avoid cross-device rename failures.
- Close sync clients, editors, and antivirus tools that may lock source folders before moving.
- Check kernel logs for the specific OS error appended to the move-failed message.
- For large moves, monitor disk space on both source and destination volumes.
When it happens
Trigger: Cross-notebook MoveDocs where the source document has sub-documents (fromFolder exists). The code at line 1864-1874 constructs absolute paths for both source and destination, removes any pre-existing destination, then calls filelock.Rename. Failure occurs on cross-device renames, permission errors, or if the source folder is locked by another process.
Common situations: Moving a document with many children between notebooks on different mount points (rename fails across filesystems). A file lock from antivirus or sync software on Windows blocks the source folder. The destination directory was removed by a concurrent operation between the IsExist check and the Rename call.
Related errors
- Move notebook [%s] file [%s] failed: %s
- rename path failed
- write publishAccess.json [%s] failed: %s
- failed to write file: %w
- export source [%s] is not a regular file
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/da33e4373bc471af.
Report an issue: GitHub.