{"record":{"id":"6de83bd9917622a0","repo":"siyuan-note/siyuan","slug":"unmarshal-workspace-conf-s-failed-s","errorCode":null,"errorMessage":"unmarshal workspace conf [%s] failed: %s","messagePattern":"unmarshal workspace conf \\[(.+?)\\] failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/working.go","lineNumber":423,"sourceCode":"\t}\n\treturn result\n}\n\nfunc ReadWorkspacePaths() (ret []string, err error) {\n\tret = []string{}\n\tworkspaceConf := filepath.Join(HomeDir, \".config\", \"siyuan\", \"workspace.json\")\n\tdata, err := os.ReadFile(workspaceConf)\n\tif err != nil {\n\t\tmsg := fmt.Sprintf(\"read 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 = gulu.JSON.UnmarshalJSON(data, &ret); err != nil {\n\t\tmsg := fmt.Sprintf(\"unmarshal 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\tvar tmp []string\n\tworkspaceBaseDir := filepath.Dir(HomeDir)\n\tfor _, d := range ret {\n\t\tif ContainerIOS == Container && strings.Contains(d, \"/Documents/\") {\n\t\t\t// iOS 端沙箱路径会变化，需要转换为相对路径再拼接当前沙箱中的工作空间基路径\n\t\t\td = d[strings.Index(d, \"/Documents/\")+len(\"/Documents/\"):]\n\t\t\td = filepath.Join(workspaceBaseDir, d)\n\t\t}\n\n\t\td = strings.TrimRight(d, \" \\t\\n\") // 去掉工作空间路径尾部空格 https://github.com/siyuan-note/siyuan/issues/6353\n\t\td = filepath.Clean(d)             // 归一化路径分隔符，清理历史持久化的斜杠差异（如 D:/foo 与 D:\\foo） https://github.com/siyuan-note/siyuan/issues/17862\n\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)","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/util/working.go#L405-L441","documentation":"After successfully reading workspace.json, ReadWorkspacePaths parses it as a JSON array of strings with gulu.JSON.UnmarshalJSON into []string. Malformed JSON (or a non-array JSON value such as an object or number) fails to unmarshal and is reported as 'unmarshal workspace conf [%s] failed: %s'.","triggerScenarios":"Any workspace API call when workspace.json contains invalid JSON — truncated file (crash mid-write), hand-edited with a syntax error, BOM or wrong encoding, or a JSON object/string instead of the expected array of path strings.","commonSituations":"Manual editing of workspace.json with trailing commas or comments; a crash or power loss leaving a partially written file; another tool overwriting the file with a different schema; non-UTF8 encoding after external modification.","solutions":["Validate the file with a JSON linter and fix the syntax error","Replace a badly corrupted workspace.json with a hand-reconstructed JSON array of your workspace paths","Restore the file from backup if one exists","Avoid hand-editing; let the SiYuan workspace switcher manage the file"],"exampleFix":"// before: workspace.json\n{\"workspaces\": [\"/home/u/ws\"]}   // object, not array\n// after\n[\"/home/u/ws\"]","handlingStrategy":"validation","validationCode":"data, _ := os.ReadFile(confPath)\nvar probe []string\nif err := json.Unmarshal(data, &probe); err != nil {\n    // corrupted or wrong shape: reset to empty registry before calling the API\n    os.WriteFile(confPath, []byte(\"[]\"), 0644)\n}","typeGuard":null,"tryCatchPattern":"paths, err := util.ReadWorkspacePaths()\nif err != nil {\n    if strings.Contains(err.Error(), \"unmarshal workspace conf\") {\n        backup(confPath)               // keep corrupted file for recovery\n        os.WriteFile(confPath, []byte(\"[]\"), 0644)\n        paths, err = util.ReadWorkspacePaths()\n    }\n    if err != nil { return err }\n}","preventionTips":["Never hand-edit workspace.json; use the in-app workspace switcher","Validate JSON before writing the file yourself","Write the file atomically (temp file + rename) to survive crashes","Keep the schema strictly as a JSON array of path strings"],"tags":["config","json","workspace"],"backgroundTag":"json-unmarshal-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"}