{"record":{"id":"0861d06e032a37e0","repo":"siyuan-note/siyuan","slug":"marshal-workspace-conf-s-failed-s","errorCode":null,"errorMessage":"marshal workspace conf [%s] failed: %s","messagePattern":"marshal workspace conf \\[(.+?)\\] failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/working.go","lineNumber":456,"sourceCode":"\t\tif gulu.File.IsDir(d) {\n\t\t\ttmp = append(tmp, d)\n\t\t} else {\n\t\t\tlogging.LogWarnf(\"workspace path [%s] is not a dir\", d)\n\t\t}\n\t}\n\tret = tmp\n\tret = DeduplicateWorkspacePaths(ret)\n\treturn\n}\n\nfunc WriteWorkspacePaths(workspacePaths []string) (err error) {\n\tworkspacePaths = DeduplicateWorkspacePaths(workspacePaths)\n\tworkspaceConf := filepath.Join(HomeDir, \".config\", \"siyuan\", \"workspace.json\")\n\tdata, err := gulu.JSON.MarshalJSON(workspacePaths)\n\tif err != nil {\n\t\tmsg := fmt.Sprintf(\"marshal workspace conf [%s] failed: %s\", workspaceConf, err)\n\t\tlogging.LogError(msg)\n\t\terr = errors.New(msg)\n\t\treturn\n\t}\n\n\tif err = filelock.WriteFile(workspaceConf, data); err != nil {\n\t\tmsg := fmt.Sprintf(\"write workspace conf [%s] failed: %s\", workspaceConf, err)\n\t\tlogging.LogError(msg)\n\t\terr = errors.New(msg)\n\t\treturn\n\t}\n\treturn\n}\n\nvar (\n\tServerURL  *url.URL // 内核服务 URL\n\tServerPort = \"0\"    // HTTP/WebSocket 端口，0 为使用随机端口\n\n\tReadOnly       bool\n\tAccessAuthCode string","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/util/working.go#L438-L474","documentation":"WriteWorkspacePaths persists the list of workspace directories to ~/.config/siyuan/workspace.json via gulu.JSON.MarshalJSON. This error means marshaling that slice to JSON failed, which is practically impossible for a []string and indicates an internal serialization fault. The original error is logged then wrapped in a new generic error, losing the %w chain.","triggerScenarios":"Calling WriteWorkspacePaths (directly or via createWorkspaceDir, removeWorkspaceDir, removeWorkspaceDirPhysically, setWorkspaceDir, Close) when gulu.JSON.MarshalJSON returns an error on the deduplicated workspace-paths slice.","commonSituations":"Rare in practice; would require a defective/older gulu version whose reflection-based marshaler fails, or a non-standard type injected into the paths slice in a fork. Effectively signals a kernel-internal bug.","solutions":["Check the kernel log for the logged underlying marshal error from logging.LogError and fix per its message","Update github.com/88250/gulu to the version pinned by kernel/go.mod (a stale vendored copy can break JSON encoding)","Verify no fork/customization altered the type of the workspace-paths slice passed to WriteWorkspacePaths","Confirm workspaceConf path (~/.config/siyuan/workspace.json) is only informational here; the failure is in-memory marshal, not disk write"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Go\nif err := util.WriteWorkspacePaths(paths); err != nil {\n    if strings.Contains(err.Error(), \"marshal workspace conf\") {\n        // log and degrade: workspace list not persisted; app still runs\n        return fmt.Errorf(\"workspace list not persisted: %w\", err)\n    }\n    return err\n}","preventionTips":["Keep gulu dependency at the version pinned in kernel/go.mod","Never put non-string values into the workspace-paths slice","Treat this error as an internal bug: check the kernel log for the original marshal error"],"tags":["go","json","serialization","workspace-config"],"backgroundTag":"json-marshal-failed","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}