{"record":{"id":"da33e4373bc471af","repo":"siyuan-note/siyuan","slug":"move-notebook-s-file-s-failed-s-da33e4","errorCode":null,"errorMessage":"Move notebook [%s] file [%s] failed: %s","messagePattern":"Move notebook \\[(.+?)\\] file \\[(.+?)\\] failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/file.go","lineNumber":1936,"sourceCode":"\tneedMoveSubDocs := fromBox.Exist(fromFolder)\n\tif needMoveSubDocs {\n\t\t// 移动子文档文件夹\n\n\t\tnewFolder := path.Join(toFolder, tree.ID)\n\t\tif isSameBox {\n\t\t\tif err = fromBox.Move(fromFolder, newFolder); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t} else {\n\t\t\tabsFromPath := filepath.Join(util.DataDir, fromBox.ID, fromFolder)\n\t\t\tabsToPath := filepath.Join(util.DataDir, toBox.ID, newFolder)\n\t\t\tif filelock.IsExist(absToPath) {\n\t\t\t\tfilelock.Remove(absToPath)\n\t\t\t}\n\t\t\tif err = filelock.Rename(absFromPath, absToPath); err != nil {\n\t\t\t\tmsg := fmt.Sprintf(Conf.Language(5), fromBox.Name, fromPath, err)\n\t\t\t\tlogging.LogErrorf(\"move [path=%s] in box [%s] failed: %s\", fromPath, fromBox.ID, err)\n\t\t\t\terr = errors.New(msg)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tnewPath = path.Join(toFolder, tree.ID+\".sy\")\n\n\tif isSameBox {\n\t\tif err = fromBox.Move(fromPath, newPath); err != nil {\n\t\t\treturn\n\t\t}\n\n\t\ttree, err = filesys.LoadTree(fromBox.ID, newPath, luteEngine)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tmoveTree(tree)","sourceCodeStart":1918,"sourceCodeEnd":1954,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/model/file.go#L1918-L1954","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the trailing OS error embedded in the message (e.g. 'The process cannot access the file') — it identifies permission vs lock vs disk","Close other SiYuan instances and sync/backup tools touching the workspace, then retry the move","Check filesystem health: write permissions on data/<toBox>/, free disk space, path length limits","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := model.MoveDocs(fromPaths, toBoxID, toPath, nil)\nif err != nil && strings.Contains(err.Error(), Conf.Language(5)[:14]) /* 'Move notebook' wrapper */ {\n\tlogging.LogWarnf(\"cross-box folder move failed, likely transient file lock: %s\", err)\n\t// verify data/<fromBox> state, close offenders, then retry the single failed path\n}","preventionTips":["Run only one kernel instance per workspace directory; extra instances defeat filelock assumptions","Exclude the workspace data dir from antivirus real-time scanning and stagger backup jobs","Prefer local filesystems over SMB/NFS for the workspace; renames there are the classic failure source"],"tags":["siyuan","filesystem","move-docs","filelock","io-error"],"backgroundTag":"file-rename-failed","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}