{"record":{"id":"aff246df23331d05","repo":"siyuan-note/siyuan","slug":"marshal-box-conf-s-failed-w","errorCode":null,"errorMessage":"marshal box conf [%s] failed: %w","messagePattern":"marshal box conf \\[(.+?)\\] failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/box.go","lineNumber":342,"sourceCode":"\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\n\tif err = box.saveConf0(newData); err != nil {\n\t\treturn err\n\t}\n\treturn syncBoxConfCryptoBackup(box.ID, persisted)","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/box.go#L324-L360","documentation":"SaveConf persists a notebook (box) configuration to <DataDir>/<boxID>/.siyuan/conf.json. Before writing it sanitizes the conf via prepareBoxConfForSave, then serializes it with gulu.JSON.MarshalIndentJSON. This error is returned when JSON marshaling of the prepared configuration fails, which is nearly impossible for plain BoxConf structs but can occur if the structure holds unmarshalable values (e.g. invalid types injected through channels, maps, or func fields).","triggerScenarios":"Calling Box.SaveConf(conf) when gulu.JSON.MarshalIndentJSON(persisted) fails; in practice this happens only if the persisted BoxConf contains a value encoding/json cannot marshal (func, channel, or a custom Marshaler returning an error), e.g. after programmatic corruption of the conf object.","commonSituations":"Plugin or test code mutating a BoxConf struct with unsupported field values; memory pressure bugs; a defective custom marshaling hook; essentially never from normal UI use.","solutions":["Inspect the BoxConf object passed to SaveConf for fields holding func, channel, or invalid values and reset them to defaults","Recreate the BoxConf with conf.NewBoxConf() and copy only known-good scalar fields before calling SaveConf","Log the wrapped inner error (%w) to identify which value failed to marshal","Update siyuan-note/gulu to the latest version in case of an encoding bug"],"exampleFix":"// before\nconf.FuncField = myFunc // unmarshalable\nerr := box.SaveConf(conf)\n// after\nconf.FuncField = nil // or remove unsupported field\nerr := box.SaveConf(conf)","handlingStrategy":"validation","validationCode":"// Go: ensure conf contains only marshalable fields before SaveConf\nb, err := json.Marshal(conf)\nif err != nil {\n    return fmt.Errorf(\"box conf not serializable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := box.SaveConf(conf); err != nil {\n    log.Printf(\"save conf failed: %v\", err) // wrapped marshal error\n}","preventionTips":["Do not inject func/channel values into BoxConf","Reset BoxConf to defaults when in doubt","Keep gulu dependency up to date"],"tags":["go","json","serialization","notebook-config"],"backgroundTag":"json-marshal-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"}