{"record":{"id":"8d852179141dd2fc","repo":"siyuan-note/siyuan","slug":"write-workspace-conf-s-failed-s","errorCode":null,"errorMessage":"write workspace conf [%s] failed: %s","messagePattern":"write workspace conf \\[(.+?)\\] failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/working.go","lineNumber":463,"sourceCode":"\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\n\tLang           = \"\"\n\n\tContainer        string // docker, android, ios, harmony, std\n\tISMicrosoftStore bool   // 桌面端是否是微软商店版\n)\n\nconst (","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/util/working.go#L445-L481","documentation":"After successfully marshaling the workspace-paths list, WriteWorkspacePaths writes the bytes to ~/.config/siyuan/workspace.json through filelock.WriteFile. This error means that locked file write failed (disk, permissions, lock contention, or path problems). The write is what registers/unregisters workspace directories in the launcher UI.","triggerScenarios":"Any caller of WriteWorkspacePaths (setWorkspaceDir, createWorkspaceDir, removeWorkspaceDir, removeWorkspaceDirPhysically, Close) when filelock.WriteFile cannot write ~/.config/siyuan/workspace.json.","commonSituations":"Read-only or full home directory; ~/.config/siyuan owned by another user (ran once as root/sudo); antivirus or backup tool holding the file; disk full; corrupted file lock state.","solutions":["Check kernel log for the underlying write error wrapped in the message","Verify ~/.config/siyuan/workspace.json is writable by the running user (ls -l, chown if it was created by root)","Free disk space / confirm the home filesystem is not mounted read-only","Close other SiYuan instances or processes locking the file, then retry","If irrecoverable, back up and remove workspace.json; it is regenerated on next workspace open"],"exampleFix":"// before: repeated 'write workspace conf failed' as root-created file\nsudo chown -R $(whoami) ~/.config/siyuan\n// after: file writable, workspace list persists normally","handlingStrategy":"validation","validationCode":"// Go: check the config file is writable before triggering workspace ops\nconf := filepath.Join(os.Getenv(\"HOME\"), \".config\", \"siyuan\", \"workspace.json\")\nif f, err := os.OpenFile(conf, os.O_WRONLY|os.O_CREATE, 0644); err != nil {\n    return fmt.Errorf(\"workspace.json not writable: %w\", err)\n} else { f.Close() }","typeGuard":null,"tryCatchPattern":"// Go\nif err := util.WriteWorkspacePaths(paths); err != nil {\n    if strings.Contains(err.Error(), \"write workspace conf\") {\n        // surface a user-facing hint about ~/.config/siyuan permissions/disk space\n        return err\n    }\n    return err\n}","preventionTips":["Never run SiYuan with sudo for the first launch - it creates root-owned files in ~/.config/siyuan","Keep a few hundred MB free on the home filesystem","Exclude ~/.config/siyuan from antivirus/backup lock contention","Check file ownership after OS/user migrations"],"tags":["go","filesystem","file-write","workspace-config"],"backgroundTag":"file-write-failed","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}