siyuan-note/siyuan · error
read session file failed: %w
Error message
read session file failed: %w
What it means
While loading the current session for a save, os.ReadFile(path) failed with an error other than os.IsNotExist — i.e. the file is probably there (or the directory is inaccessible) but the kernel cannot read it (kernel/agent/session.go:379-380). The raw OS error is wrapped with %w, so the cause (permission, I/O, path length) is visible in the message.
Source
Thrown at kernel/agent/session.go:380
}
return currentRevision, existingData, nil
}
if meta.ExpectedRevision != nil && *meta.ExpectedRevision != currentRevision {
return currentRevision, nil, ErrSessionConflict
}
for k, v := range existingData {
if _, ok := newData[k]; !ok {
// messages 是已废弃的旧会话字段,不再带入新格式;其他未知字段原样保留,
// 避免前后端版本不一致时擦除较新版本写入的数据。
if k != "messages" && k != "expectedRevision" && k != "commitTurnID" &&
k != "recoveryTurnID" && k != "recoveryState" && k != "recoveryRevision" && k != "agentRunning" {
newData[k] = v
}
}
}
}
} else if err != nil && !os.IsNotExist(err) {
return 0, nil, fmt.Errorf("read session file failed: %w", err)
} else if meta.ExpectedRevision != nil && *meta.ExpectedRevision != 0 {
return 0, nil, ErrSessionConflict
}
if commitTurnID != "" {
runtime, err := loadRuntimeLocked(meta.ID)
if err != nil {
return currentRevision, nil, fmt.Errorf("read agent runtime failed: %w", err)
}
if runtime.ActiveTurn != nil {
if runtime.ActiveTurn.TurnID != commitTurnID {
return currentRevision, nil, ErrSessionConflict
}
if !isRuntimeTurnTerminal(runtime.ActiveTurn) {
return currentRevision, nil, ErrRuntimeNotFinalized
}
if err := applyRuntimeTurnToSessionLocked(newData, runtime.ActiveTurn); err != nil {
return currentRevision, nil, err
}View on GitHub (pinned to afa823b6b4)
Solutions
- Read the wrapped errno in the message: EACCES/EPERM → fix ownership (chown/chmod) on workspace/data/storage/ai/agent; EIO/ENOTCONN → remount the workspace volume
- Verify the kernel process user can cat the session.json file
- On Windows, exclude the workspace from antivirus real-time scanning or wait for the backup lock to release
- Retry the save only after the underlying access problem is fixed
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: kernel process must be able to read the session dir // (run as the same user the kernel runs under) // ls -la <workspace>/data/storage/ai/agent/sessions/<id>/session.json
Type guard
null
Try / catch
catch (e) {
if (/read session file failed/.test(e?.data?.msg ?? '')) {
// inspect wrapped errno; fix ownership/mount, then retry once
}
} Prevention
- Run the kernel under a user that owns the workspace tree
- Avoid network-mounted workspaces for live agent sessions
- On Windows, exclude the workspace from antivirus locks
When it happens
Trigger: POST /api/ai/agent/saveSession when data/storage/ai/agent/sessions/<id>/session.json or a parent directory has wrong ownership/permissions (EACCES), the workspace is on an unmounted/network volume (EIO, ENOTCONN), or the path exceeds OS limits. Distinct from a first-time save: file-not-exist is expected and handled, everything else is fatal.
Common situations: Workspace copied between machines with different UIDs; running the kernel under a service account without read access; antivirus or backup software holding an exclusive lock on Windows; a removable/network drive dropping out mid-session.
Related errors
- create session dir failed: %w
- save session file failed: %w
- invalid frontend capability ID: %s
- unsupported agent runtime schema version: %d
- agent session revision conflict
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/7aec418c847b7b18.
Report an issue: GitHub.