{"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":"critical","filePath":"kernel/model/box.go","lineNumber":384,"sourceCode":"\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\tif !ast.IsNodeIDPattern(box.ID) {\n\t\treturn fmt.Errorf(\"invalid box ID [%s]\", box.ID)\n\t}\n\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":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/box.go#L366-L402","documentation":"saveConf0 writes the serialized conf.json through filelock.WriteFile; on failure it reports a filesystem-fatal error and returns this wrapped error. It means the notebook configuration could not be persisted to <DataDir>/<boxID>/.siyuan/conf.json.","triggerScenarios":"Calling Box.SaveConf when filelock.WriteFile fails: read-only filesystem, permission denied on the existing conf.json, disk full, file locked by another process, or antivirus blocking the write.","commonSituations":"conf.json owned by another user after running SiYuan as root/admin once; OneDrive/Dropbox sync locking the file on Windows; disk quota exceeded; workspace folder moved or unmounted while running.","solutions":["Check permissions/ownership of <DataDir>/<boxID>/.siyuan/conf.json and make it writable by the process user","Free disk space if the volume is full","Close other programs (sync clients, editors) holding a lock on conf.json","Check the kernel log for the ReportFileSysFatalError detail to identify the exact OS error","Restart SiYuan after fixing the filesystem to re-attempt persistence"],"exampleFix":"// before (Linux)\nls -l conf.json  # owned by root, mode 0644\n// after\nsudo chown $USER:$USER conf.json && chmod u+w conf.json","handlingStrategy":"try-catch","validationCode":"// Go: check the target file is writable first\np := filepath.Join(util.DataDir, box.ID, \".siyuan/conf.json\")\nif f, err := os.OpenFile(p, os.O_WRONLY, 0); err != nil {\n    return fmt.Errorf(\"conf.json not writable: %w\", err)\n} else {\n    f.Close()\n}","typeGuard":null,"tryCatchPattern":"if err := box.SaveConf(conf); err != nil {\n    if strings.Contains(err.Error(), \"write box conf\") {\n        // inspect kernel log ReportFileSysFatalError detail, fix fs, restart\n    }\n}","preventionTips":["Exclude the workspace from sync tools locking conf.json","Avoid running SiYuan as root/admin which changes file ownership","Keep free disk space","Close other SiYuan instances before editing"],"tags":["go","filesystem","file-write","notebook-config"],"backgroundTag":"file-write-failed","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}