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

  1. Check the wrapped errno: EACCES → chmod/chown workspace/data/storage/ai/agent; EROFS → remount workspace read-write; ENOSPC → free space
  2. Remove any regular file at data/storage/ai/agent/sessions/<id> so MkdirAll can create the directory
  3. Verify with `sudo -u <kernel-user> mkdir -p` that the path is creatable
  4. 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

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


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/8b75f48c1fc44953. Report an issue: GitHub.