siyuan-note/siyuan · error
unsupported agent runtime schema version: %d
Error message
unsupported agent runtime schema version: %d
What it means
filelock.WriteFile failed to persist ~/.config/siyuan/workspace.json inside util.WriteWorkspacePaths. The JSON serialized fine but the disk write failed: no permission on ~/.config/siyuan, a read-only home filesystem, disk full, or the filelock layer unable to acquire/create its lock artifacts. The underlying error is appended.
Source
Thrown at kernel/agent/runtime.go:204
func runtimePath(sessionID string) string {
return filepath.Join(sessionsDir(), sessionID, "runtime.json")
}
func loadRuntimeLocked(sessionID string) (*agentRuntime, error) {
data, err := os.ReadFile(runtimePath(sessionID))
if err != nil {
if os.IsNotExist(err) {
return &agentRuntime{SchemaVersion: 1, SessionID: sessionID}, nil
}
return nil, err
}
var runtime agentRuntime
if err := gulu.JSON.UnmarshalJSON(data, &runtime); err != nil {
return nil, err
}
if runtime.SchemaVersion > 1 {
return nil, fmt.Errorf("unsupported agent runtime schema version: %d", runtime.SchemaVersion)
}
if runtime.SessionID != "" && runtime.SessionID != sessionID {
return nil, fmt.Errorf("agent runtime session id mismatch")
}
if runtime.Revision < 0 {
return nil, fmt.Errorf("invalid agent runtime revision")
}
if runtime.ActiveTurn != nil {
if runtime.ActiveTurn.TurnID == "" {
return nil, fmt.Errorf("invalid agent runtime turn id")
}
switch runtime.ActiveTurn.State {
case "running", "finished", "interrupted":
default:
return nil, fmt.Errorf("invalid agent runtime turn state")
}
}
if runtime.SchemaVersion == 0 {View on GitHub (pinned to afa823b6b4)
Solutions
- Read the appended error: 'permission denied' -> chown -R <kerneluser> ~/.config/siyuan (or chmod u+w); 'no space left on device' -> free space
- Ensure the service/container sets HOME to a writable directory for the user the kernel runs as
- Verify the directory exists: mkdir -p ~/.config/siyuan with the right ownership
- On NFS-like filesystems, move the config dir to local storage or ensure lock files can be created in it
Example fix
# before: container runs as root but HOME volume owned by uid 1000 HOME=/home/siyuan # after: align user and ownership user: "1000:1000" volumes: ["/path/home:/home/siyuan"] # and on the host: chown -R 1000:1000 /path/home/.config/siyuan
Defensive patterns
Strategy: retry
Validate before calling
confDir := filepath.Join(home, ".config", "siyuan")
if err := os.MkdirAll(confDir, 0755); err != nil {
return fmt.Errorf("cannot prepare %s: fix permissions before workspace switch", confDir)
} Type guard
null
Try / catch
err := util.WriteWorkspacePaths(paths)
if err != nil && strings.Contains(err.Error(), "write workspace conf") {
time.Sleep(500 * time.Millisecond) // lock contention is transient
err = util.WriteWorkspacePaths(paths)
} Prevention
- Run the kernel under a user that owns ~/.config/siyuan; verify with ls -ld at deploy time
- Set HOME explicitly (and writable) in systemd/Docker units
- Avoid concurrent kernel instances sharing one home dir; their file locks and writes will fight
When it happens
Trigger: Switching or closing a workspace when the kernel user cannot write ~/.config/siyuan (ownership mismatch after container/user migration), HOME points somewhere read-only (systemd unit without proper env), disk quota exhausted, or an NFS/home mount denying the lock file creation used by filelock.
Common situations: Docker or systemd deployments where HOME is unset or owned by root; multi-user machines with restrictive home permissions; disk-full events; network home directories (NFS/Lustre) that interact badly with lock files.
Related errors
- invalid frontend capability ID: %s
- write data [%s] failed: %s
- get history directory failed: %w
- create history directory [%s] failed: %w
- copy asset [%s] to [%s] failed: %w
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/ad34bd7739dbb499.
Report an issue: GitHub.