{"record":{"id":"9cf4a20c4501436f","repo":"siyuan-note/siyuan","slug":"create-conf-dir-failed-w","errorCode":null,"errorMessage":"create conf dir failed: %w","messagePattern":"create conf dir failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/file.go","lineNumber":3064,"sourceCode":"\nfunc (box *Box) addMaxSort(parentPath, id string) {\n\tif err := box.placeDocInSiblingOrder(parentPath, id, \"\", \"after\"); nil != err {\n\t\tlogging.LogErrorf(\"append document sort failed: %s\", err)\n\t}\n}\n\nfunc (box *Box) addMinSort(parentPath, id string) {\n\tif err := box.placeDocInSiblingOrder(parentPath, id, \"\", \"before\"); nil != err {\n\t\tlogging.LogErrorf(\"prepend document sort failed: %s\", err)\n\t}\n}\n\nfunc (box *Box) placeDocInSiblingOrder(parentPath, id, targetID, position string) error {\n\tfileTreeSortLock.Lock()\n\tconfDir := filepath.Join(util.DataDir, box.ID, \".siyuan\")\n\tif err := os.MkdirAll(confDir, 0755); nil != err {\n\t\tfileTreeSortLock.Unlock()\n\t\treturn fmt.Errorf(\"create conf dir failed: %w\", err)\n\t}\n\tconfPath := filepath.Join(confDir, \"sort.json\")\n\tfullSortIDs, err := readSortConfMap(confPath)\n\tif nil != err {\n\t\tfileTreeSortLock.Unlock()\n\t\treturn err\n\t}\n\tcurrentIDs, err := loadSiblingCustomOrder(box.ID, parentPath, fullSortIDs)\n\tif nil != err {\n\t\tfileTreeSortLock.Unlock()\n\t\treturn err\n\t}\n\torderedIDs := make([]string, 0, len(currentIDs)+1)\n\tfor _, currentID := range currentIDs {\n\t\tif currentID != id {\n\t\t\torderedIDs = append(orderedIDs, currentID)\n\t\t}\n\t}","sourceCodeStart":3046,"sourceCodeEnd":3082,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/file.go#L3046-L3082","documentation":"This error occurs when SiYuan tries to create the per-notebook configuration directory `<data>/<boxID>/.siyuan` (holding sort.json) with os.MkdirAll before persisting a custom document sort order, and the OS call fails. The wrapped OS error is included via %w. It aborts the sibling-order placement of a document to avoid writing sort config into an inconsistent location.","triggerScenarios":"Calling the document sort/placement path (placeDocInSiblingOrder, reached via doc tree sort APIs) when the parent directory cannot be created: the notebook directory was deleted or renamed on disk while the kernel still knows the box, filesystem permission denies mkdir, disk full, or DataDir sits on a read-only/removable mount.","commonSituations":"Notebook folder removed by an external sync tool while SiYuan is running; workspace moved to a read-only volume; running as a user without write permission to the data directory; disk-quota exhaustion on the OS/Cloud-Drive mounted workspace.","solutions":["Verify the notebook folder exists under the workspace data directory; recreate or re-open the notebook if it was deleted externally","Check and fix filesystem permissions on <workspace>/data/<boxID> (writable by the kernel process user)","Free disk space / resolve quota limits on the volume holding the workspace","If the workspace is on a network/cloud mount, ensure it is mounted read-write and not in an offline state","Inspect the wrapped %w error in logs for the exact OS cause"],"exampleFix":"// before (failing because notebook dir was removed)\nos.MkdirAll(filepath.Join(util.DataDir, box.ID, \".siyuan\"), 0755) // mkdir: no such file or directory\n// after (caller-side guard: ensure the box directory exists first)\nif _, err := os.Stat(filepath.Join(util.DataDir, box.ID)); os.IsNotExist(err) {\n    return fmt.Errorf(\"notebook [%s] directory is missing\", box.ID)\n}\nif err := os.MkdirAll(filepath.Join(util.DataDir, box.ID, \".siyuan\"), 0755); err != nil {\n    return fmt.Errorf(\"create conf dir failed: %w\", err)\n}","handlingStrategy":"validation","validationCode":"const dirOk = await fetchPost('/api/notebook/lsNotebooks', {});\nconst box = dirOk.data.notebooks.find(n => n.id === boxId);\nif (!box) throw new Error(`Notebook ${boxId} is missing or closed`);","typeGuard":"// Go\nfunc boxWritable(boxID string) bool {\n    info, err := os.Stat(filepath.Join(util.DataDir, boxID))\n    return err == nil && info.IsDir()\n}","tryCatchPattern":"try {\n  await reorderDocs(sourceIDs, targetID, position);\n} catch (e) {\n  if (String(e).includes('create conf dir failed')) {\n    showMsg('Notebook data directory is not writable; check permissions/disk', true);\n  }\n}","preventionTips":["Keep the workspace on a local read-write volume, not an offline cloud mount","Do not delete or rename notebook folders under data/ while SiYuan is running","Monitor available disk space on the workspace volume","Exclude the workspace data directory from external sync tools that rename folders mid-write"],"tags":["filesystem","io","mkdir","notebook"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}