{"record":{"id":"bd4dcf633093b581","repo":"siyuan-note/siyuan","slug":"read-agent-runtime-failed-w","errorCode":null,"errorMessage":"read agent runtime failed: %w","messagePattern":"read agent runtime failed: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"kernel/agent/session.go","lineNumber":387,"sourceCode":"\t\t\t\tif _, ok := newData[k]; !ok {\n\t\t\t\t\t// messages 是已废弃的旧会话字段，不再带入新格式；其他未知字段原样保留，\n\t\t\t\t\t// 避免前后端版本不一致时擦除较新版本写入的数据。\n\t\t\t\t\tif k != \"messages\" && k != \"expectedRevision\" && k != \"commitTurnID\" &&\n\t\t\t\t\t\tk != \"recoveryTurnID\" && k != \"recoveryState\" && k != \"recoveryRevision\" && k != \"agentRunning\" {\n\t\t\t\t\t\tnewData[k] = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if err != nil && !os.IsNotExist(err) {\n\t\treturn 0, nil, fmt.Errorf(\"read session file failed: %w\", err)\n\t} else if meta.ExpectedRevision != nil && *meta.ExpectedRevision != 0 {\n\t\treturn 0, nil, ErrSessionConflict\n\t}\n\tif commitTurnID != \"\" {\n\t\truntime, err := loadRuntimeLocked(meta.ID)\n\t\tif err != nil {\n\t\t\treturn currentRevision, nil, fmt.Errorf(\"read agent runtime failed: %w\", err)\n\t\t}\n\t\tif runtime.ActiveTurn != nil {\n\t\t\tif runtime.ActiveTurn.TurnID != commitTurnID {\n\t\t\t\treturn currentRevision, nil, ErrSessionConflict\n\t\t\t}\n\t\t\tif !isRuntimeTurnTerminal(runtime.ActiveTurn) {\n\t\t\t\treturn currentRevision, nil, ErrRuntimeNotFinalized\n\t\t\t}\n\t\t\tif err := applyRuntimeTurnToSessionLocked(newData, runtime.ActiveTurn); err != nil {\n\t\t\t\treturn currentRevision, nil, err\n\t\t\t}\n\t\t} else if currentCommittedTurnID != commitTurnID {\n\t\t\treturn currentRevision, nil, ErrSessionConflict\n\t\t}\n\t}\n\n\tnewRevision := currentRevision + 1\n\tnewData[\"revision\"] = newRevision","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/agent/session.go#L369-L405","documentation":"When a save carries a commitTurnID (or recoveryTurnID), SaveSessionState loads the per-session agent runtime state to verify and apply the finished turn (kernel/agent/session.go:384-387). If loadRuntimeLocked fails — the runtime state file is unreadable or corrupt — the commit is refused with 'read agent runtime failed' because committing without the runtime's authoritative turn content would lose data.","triggerScenarios":"POST /api/ai/agent/saveSession with commitTurnID while the session's runtime state file (alongside session.json in data/storage/ai/agent/sessions/<id>/) is corrupt, zero-length, or unreadable — typically after a crash between writing runtime state and session.json, or partial sync of the workspace.","commonSituations":"Kernel killed mid-turn so the runtime file was half-written; workspace synchronized externally and the runtime file conflicted; disk issues. Often accompanied by the same session recovering oddly on next getSession (which runs FinalizeOrphanedTurn).","solutions":["GET /api/ai/agent/getSession first — its FinalizeOrphanedTurn pass (kernel/api/agent.go:441) can repair/finalize an orphaned runtime turn so the subsequent commit succeeds","Inspect the session directory for a truncated runtime state file and restore it from backup","If unrepairable, remove the session (removeSession) and start a new one — the turn's runtime content is the authoritative record and must not be hand-faked","Check what crashed or interrupted the write (power, OOM-kill, sync tool) to avoid recurrence"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"catch (e) {\n  if (/read agent runtime failed/.test(e?.data?.msg ?? '')) {\n    // first try GET /api/ai/agent/getSession to trigger FinalizeOrphanedTurn repair,\n    // then retry the commit with the same commitTurnID exactly once\n  }\n}","preventionTips":["Always GET the session after a kernel crash before committing turns","Do not delete runtime state files manually to 'clean up' — they hold the authoritative turn content"],"tags":["agent","runtime","corruption","turn-commit"],"backgroundTag":"corrupted-state-file","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}