siyuan-note/siyuan · error
create session dir failed: %w
Error message
create session dir failed: %w
What it means
SaveSessionState creates the per-session directory data/storage/ai/agent/sessions/<id>/ before writing session.json (kernel/agent/session.go:414-415). os.MkdirAll failure is wrapped as 'create session dir failed'. Since the id already passed the 20-char [0-9a-z] gate, a failure here is environmental: permissions, read-only filesystem, or a non-directory occupying the path.
Source
Thrown at kernel/agent/session.go:415
return currentRevision, nil, err
}
} else if currentCommittedTurnID != commitTurnID {
return currentRevision, nil, ErrSessionConflict
}
}
newRevision := currentRevision + 1
newData["revision"] = newRevision
if commitTurnID != "" {
newData["lastCommittedTurnID"] = commitTurnID
}
data, err = gulu.JSON.MarshalIndentJSON(newData, "", "\t")
if err != nil {
return currentRevision, nil, fmt.Errorf("encode session data failed: %w", err)
}
if err := os.MkdirAll(dir, 0755); err != nil {
return currentRevision, nil, fmt.Errorf("create session dir failed: %w", err)
}
if err := filelock.WriteFile(path, data); err != nil {
return currentRevision, nil, fmt.Errorf("save session file failed: %w", err)
}
if commitTurnID != "" {
if err := markRuntimeCommittedLocked(meta.ID, commitTurnID); err != nil {
logging.LogWarnf("commit agent runtime failed: %s", err)
}
}
title, _ := newData["title"].(string)
if title == "" {
title = "AI Agent"
}
createdAt := meta.CreatedAt
if value := numberToInt64(newData["createdAt"]); value > 0 {
createdAt = value
}View on GitHub (pinned to afa823b6b4)
Solutions
- Check the wrapped errno: EACCES → chmod/chown workspace/data/storage/ai/agent; EROFS → remount workspace read-write; ENOSPC → free space
- Remove any regular file at data/storage/ai/agent/sessions/<id> so MkdirAll can create the directory
- Verify with `sudo -u <kernel-user> mkdir -p` that the path is creatable
- Retry the identical save once the environment is fixed — no partial state was written
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight writability probe // test -w <workspace>/data/storage/ai/agent && echo writable
Type guard
null
Try / catch
catch (e) {
if (/create session dir failed/.test(e?.data?.msg ?? '')) {
// check errno: EACCES/EROFS/ENOSPC; fix mount/ownership; remove file blocking the dir name; retry
}
} Prevention
- Ensure the workspace is on a writable mount with space headroom
- Never pre-create a regular file named like a session id under sessions/
When it happens
Trigger: First save of a new session when the workspace or storage/ai/agent tree is not writable (EACCES/EROFS), the workspace volume is full or unmounted (ENOSPC/ENXIO), or a file named exactly like the session id exists under sessions/ (ENOTDIR/EEXIST).
Common situations: Workspace on a read-only mount (Docker with ro volume, locked snapshot); kernel run as a different user than the one owning the workspace; leftover artifact where the directory should be; CI environments writing into a container path with a small tmpfs.
Related errors
- read session file failed: %w
- save session file failed: %w
- agent session revision conflict
- invalid session id
- invalid session data
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/8b75f48c1fc44953.
Report an issue: GitHub.