siyuan-note/siyuan · warning
-1
-1
Error message
read workspace conf [%s] failed: %s
What it means
Logged and returned at working.go:404 when os.ReadFile of the workspace config (~/.config/siyuan/workspace.json, built from HomeDir at working.go:399) fails. code=-1 marks it as a generic (non-SiYuan-specific) error. The file holds the list of recently used workspace directory paths. Note: on a genuinely fresh install the file does not exist yet, so callers must treat not-exist as benign.
Source
Thrown at kernel/util/working.go:404
targetLower := strings.ToLower(target)
var result []string
for _, p := range paths {
if strings.ToLower(p) == targetLower {
continue
}
result = append(result, p)
}
return result
}
func ReadWorkspacePaths() (ret []string, err error) {
ret = []string{}
workspaceConf := filepath.Join(HomeDir, ".config", "siyuan", "workspace.json")
data, err := os.ReadFile(workspaceConf)
if err != nil {
msg := fmt.Sprintf("read workspace conf [%s] failed: %s", workspaceConf, err)
logging.LogError(msg)
err = errors.New(msg)
return
}
if err = gulu.JSON.UnmarshalJSON(data, &ret); err != nil {
msg := fmt.Sprintf("unmarshal workspace conf [%s] failed: %s", workspaceConf, err)
logging.LogError(msg)
err = errors.New(msg)
return
}
var tmp []string
workspaceBaseDir := filepath.Dir(HomeDir)
for _, d := range ret {
if ContainerIOS == Container && strings.Contains(d, "/Documents/") {
// iOS 端沙箱路径会变化,需要转换为相对路径再拼接当前沙箱中的工作空间基路径
d = d[strings.Index(d, "/Documents/")+len("/Documents/"):]
d = filepath.Join(workspaceBaseDir, d)
}View on GitHub (pinned to 251596fc0d)
Solutions
- Treat a not-exist error as non-fatal and let the user pick a workspace to regenerate the file.
- Ensure ~/.config/siyuan exists and is writable by the SiYuan process.
- If the file was deleted by mistake, choose a workspace once — WriteWorkspacePaths recreates it.
- On sandboxed installs, confirm HomeDir resolves inside the writable sandbox.
Defensive patterns
Strategy: fallback
Validate before calling
// Treat a missing workspace.json as benign (fresh install),
// and only act on other read errors.
func workspaceConfReadable() error {
p := filepath.Join(util.HomeDir, ".config", "siyuan", "workspace.json")
_, err := os.Stat(p)
if err == nil {
return nil
}
if os.IsNotExist(err) {
return nil // expected on first run
}
return err
} Type guard
func isReadWorkspaceConfFailed(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "read workspace conf")
} Try / catch
paths, err := util.ReadWorkspacePaths()
if err != nil {
if os.IsNotExist(underlyingOSErr(err)) {
paths = nil // first run: prompt the user to pick a workspace
} else {
// fall back to a default workspace location
paths = []string{defaultWorkspacePath()}
}
} Prevention
- On fresh installs, expect this file to be absent — handle not-exist as a normal case.
- Ensure ~/.config/siyuan is writable so the file can be (re)created.
- Do not delete workspace.json casually; if you do, pick a workspace once to regenerate it.
When it happens
Trigger: First run before any workspace has been chosen (file absent), permission denied on ~/.config/siyuan, the directory was moved/deleted out of band, another process holds an incompatible handle, or the path is on an unavailable volume.
Common situations: Fresh install, user manually deleted workspace.json, HomeDir mis-detected on a portable/custom layout, snap/flatpak confinement, read-only home.
Related errors
- directory not found: %s
- not a valid workspace: %s
- resolve assets directory [%s] failed: %w
- [%s] is not sub path of workspace
- resolve assets root [%s] failed: %w
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/79f57418223b7639.
Report an issue: GitHub.