{"record":{"id":"5e01fd2c2b1f3d64","repo":"siyuan-note/siyuan","slug":"write-box-conf-s-failed-w","errorCode":null,"errorMessage":"write box conf [%s] failed: %w","messagePattern":"write box conf \\[(.+?)\\] failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/box.go","lineNumber":329,"sourceCode":"\nfunc syncBoxConfCryptoBackup(boxID string, boxConf *conf.BoxConf) error {\n\tif !boxConf.Encrypted || boxConf.BoxCrypt == nil {\n\t\treturn nil\n\t}\n\tif needWriteNotebookCryptBackup(boxID, boxConf.BoxCrypt) {\n\t\treturn writeNotebookCryptBackup(boxID, boxConf.BoxCrypt)\n\t}\n\treturn nil\n}\n\nfunc (box *Box) saveConf0(data []byte) error {\n\tconfPath := filepath.Join(util.DataDir, box.ID, \".siyuan/conf.json\")\n\tif err := os.MkdirAll(filepath.Join(util.DataDir, box.ID, \".siyuan\"), 0755); err != nil {\n\t\treturn fmt.Errorf(\"mkdir box conf dir failed: %w\", err)\n\t}\n\tif err := filelock.WriteFile(confPath, data); err != nil {\n\t\tutil.ReportFileSysFatalError(err)\n\t\treturn fmt.Errorf(\"write box conf [%s] failed: %w\", confPath, err)\n\t}\n\tinvalidateEncryptedPublishAccessCache()\n\treturn nil\n}\n\n// validateBoxPath 校验 box 内相对路径，拒绝 .. 和绝对路径，确保最终路径在 <DataDir>/<boxID>/ 内。\nfunc (box *Box) validateBoxPath(p string) (string, error) {\n\treturn filesys.ValidateBoxRelativePath(box.ID, p)\n}\n\nfunc (box *Box) Ls(p string) (ret []*FileInfo, totals int, err error) {\n\tif _, err = box.validateBoxPath(p); err != nil {\n\t\treturn\n\t}\n\tboxLocalPath := filepath.Join(util.DataDir, box.ID)\n\tif before, ok := strings.CutSuffix(p, \".sy\"); ok {\n\t\tdir := before\n\t\tabsDir := filepath.Join(boxLocalPath, dir)","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/box.go#L311-L347","documentation":"In saveConf0, after the directory is created, filelock.WriteFile(confPath, data) writes conf.json; on failure it calls util.ReportFileSysFatalError(err) (which escalates fatal FS conditions kernel-wide) and returns fmt.Errorf('write box conf [%s] failed: %w', confPath, err). This is the actual disk write of the notebook configuration.","triggerScenarios":"Any Box.SaveConf where the write to <DataDir>/<boxID>/.siyuan/conf.json fails: disk full mid-write, the volume unmounted under the kernel, a file-lock/permission failure, or the directory removed by another process between mkdir and write.","commonSituations":"USB/network drive holding the workspace dropped out; ENOSPC during a large session; antivirus/backup software locking conf.json on Windows; another SiYuan instance (or a sync tool) holds/removes the file.","solutions":["Free space on / remount the data volume and retry the save.","Close other SiYuan instances sharing the workspace (filelock serializes within one instance, not across sync tools).","On Windows, exclude the workspace from AV/on-demand backup that may lock the file.","If ReportFileSysFatalError fired, follow the kernel's fatal-FS handling — the workspace is likely unavailable and the kernel may need a restart."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Check free space / writability before a configuration save.\nif err := filelock.WriteFile(filepath.Join(util.DataDir, \".writeprobe\"), []byte{0}); err != nil {\n    return fmt.Errorf(\"data dir not writable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"// Fatal FS errors are escalated by ReportFileSysFatalError; surface them prominently.\nif err := box.SaveConf(conf); err != nil && strings.Contains(err.Error(), \"write box conf\") {\n    showFatalDiskError(errors.Unwrap(err))\n}","preventionTips":["Keep the data volume mounted and below quota.","Avoid running two SiYuan instances against one workspace.","On Windows, exclude the workspace from AV/backup tools that lock conf.json."],"tags":["filesystem","notebook","config","permissions","disk-full"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}