{"record":{"id":"4189937a52e9b032","repo":"siyuan-note/siyuan","slug":"prepare-box-conf-s-failed-w","errorCode":null,"errorMessage":"prepare box conf [%s] failed: %w","messagePattern":"prepare box conf \\[(.+?)\\] failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/box.go","lineNumber":338,"sourceCode":"\t\tlogging.LogErrorf(\"parse box conf [%s] failed: %s\", confPath, err)\n\t\treturn\n\t}\n\n\tif ret.Encrypted {\n\t\tif err = revealBoxMetadataIfUnlocked(box.ID, ret); err != nil {\n\t\t\tlogging.LogErrorf(\"decrypt encrypted notebook metadata [%s] failed: %s\", box.ID, err)\n\t\t}\n\t} else {\n\t\tret.Icon = filterBoxIcon(ret.Icon)\n\t}\n\treturn\n}\n\nfunc (box *Box) SaveConf(conf *conf.BoxConf) error {\n\tconfPath := filepath.Join(util.DataDir, box.ID, \".siyuan/conf.json\")\n\tpersisted, err := prepareBoxConfForSave(box.ID, conf)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"prepare box conf [%s] failed: %w\", confPath, err)\n\t}\n\tnewData, err := gulu.JSON.MarshalIndentJSON(persisted, \"\", \"  \")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshal box conf [%s] failed: %w\", confPath, err)\n\t}\n\n\toldData, err := filelock.ReadFile(confPath)\n\tif err != nil {\n\t\tif err = box.saveConf0(newData); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn syncBoxConfCryptoBackup(box.ID, persisted)\n\t}\n\n\tif bytes.Equal(newData, oldData) {\n\t\treturn syncBoxConfCryptoBackup(box.ID, persisted)\n\t}\n","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/box.go#L320-L356","documentation":"Box.SaveConf persists a notebook's .siyuan/conf.json. Before writing, prepareBoxConfForSave validates/normalizes the configuration; if that preparation fails, the error is wrapped as \"prepare box conf [<path>] failed: <cause>\". The inner cause carries the actual problem (e.g. an invalid field value or type in the BoxConf), while the outer message identifies which notebook's conf file was involved.","triggerScenarios":"Any API path that saves notebook configuration while prepareBoxConfForSave returns an error — e.g. setting a box conf field to a value that fails validation (invalid type, out-of-range or forbidden value) via conf-saving endpoints or API contract tests exercising block/heading transactions that touch box conf.","commonSituations":"A client (plugin, script, third-party tool) posting a malformed box configuration to the kernel API; stale or hand-edited conf.json contents clashing with the validator; regression tests feeding unusual conf values.","solutions":["Read the wrapped cause after 'failed:' — it names the exact field or validation that rejected the conf","Fix the offending BoxConf field on the client side and retry the save","Restore a known-good .siyuan/conf.json for the notebook if the on-disk file is corrupted or hand-edited","If triggered programmatically, validate the conf object before calling SaveConf"],"exampleFix":"// before: posting invalid conf\nfetchPost(\"/api/notebook/saveConf notebook\", {notebook: boxID, conf: {sortMode: \"not-a-number\"}})\n// after\nfetchPost(\"/api/notebook/saveConf notebook\", {notebook: boxID, conf: {sortMode: 0}})","handlingStrategy":"try-catch","validationCode":"function validateBoxConfBeforeSave(conf) {\n  // mirror prepareBoxConfForSave checks: required fields present, types correct\n  return conf != null && typeof conf === \"object\";\n}","typeGuard":"function isBoxConf(c) {\n  return typeof c === \"object\" && c !== null && !Array.isArray(c);\n}","tryCatchPattern":"err := box.SaveConf(conf)\nif err != nil {\n  var wrapped = err.Error() // \"prepare box conf [<path>] failed: <cause>\"\n  // log wrapped cause and surface to caller; do not retry blindly\n}","preventionTips":["Always inspect the wrapped cause after 'failed:' — it identifies the offending conf field","Do not hand-edit .siyuan/conf.json; change settings through the API/UI","Keep clients updated with the BoxConf schema","Validate conf payloads before calling save endpoints"],"tags":["notebook","configuration","persistence"],"backgroundTag":"invalid-config-value","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"}