{"record":{"id":"2222498d9cceffdb","repo":"siyuan-note/siyuan","slug":"invalid-agent-runtime-turn-id","errorCode":null,"errorMessage":"invalid agent runtime turn id","messagePattern":"invalid agent runtime turn id","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/agent/runtime.go","lineNumber":214,"sourceCode":"\t\t}\n\t\treturn nil, err\n\t}\n\tvar runtime agentRuntime\n\tif err := gulu.JSON.UnmarshalJSON(data, &runtime); err != nil {\n\t\treturn nil, err\n\t}\n\tif runtime.SchemaVersion > 1 {\n\t\treturn nil, fmt.Errorf(\"unsupported agent runtime schema version: %d\", runtime.SchemaVersion)\n\t}\n\tif runtime.SessionID != \"\" && runtime.SessionID != sessionID {\n\t\treturn nil, fmt.Errorf(\"agent runtime session id mismatch\")\n\t}\n\tif runtime.Revision < 0 {\n\t\treturn nil, fmt.Errorf(\"invalid agent runtime revision\")\n\t}\n\tif runtime.ActiveTurn != nil {\n\t\tif runtime.ActiveTurn.TurnID == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"invalid agent runtime turn id\")\n\t\t}\n\t\tswitch runtime.ActiveTurn.State {\n\t\tcase \"running\", \"finished\", \"interrupted\":\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"invalid agent runtime turn state\")\n\t\t}\n\t}\n\tif runtime.SchemaVersion == 0 {\n\t\truntime.SchemaVersion = 1\n\t}\n\tif runtime.SessionID == \"\" {\n\t\truntime.SessionID = sessionID\n\t}\n\treturn &runtime, nil\n}\n\nfunc writeRuntimeLocked(sessionID string, runtime *agentRuntime) error {\n\tif runtime == nil {","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/agent/runtime.go#L196-L232","documentation":"When the persisted runtime has an ActiveTurn, loadRuntimeLocked requires its TurnID to be non-empty. An active turn without an identifier is an un-referencable in-flight record, so the whole runtime load fails rather than resuming a turn that cannot be committed or recovered.","triggerScenarios":"Loading any session whose runtime JSON contains an activeTurn object with turnID set to \"\" or missing; a partially written or hand-trimmed runtime file; serialization bugs that dropped the field.","commonSituations":"Corruption from an interrupted write combined with a non-atomic file replacement; manual editing; a third-party tool modifying session state.","solutions":["Set the active turn's turnID to the real turn identifier, or remove the activeTurn object entirely if no turn is in flight","Restore the runtime file from workspace backup","Let the kernel regenerate the runtime by clearing the session's runtime state if recovery is acceptable"],"exampleFix":"// before (runtime JSON)\n\"activeTurn\": {\"turnID\": \"\", \"state\": \"running\"}\n// after\n\"activeTurn\": null","handlingStrategy":"validation","validationCode":"const runtime = JSON.parse(readRuntimeFile(sessionDir));\nif (runtime.activeTurn && !runtime.activeTurn.turnID) throw new Error(\"activeTurn missing turnID\");","typeGuard":"function hasValidActiveTurn(r: Runtime): boolean { return r.activeTurn == null || (typeof r.activeTurn.turnID === \"string\" && r.activeTurn.turnID !== \"\"); }","tryCatchPattern":null,"preventionTips":["Never write partial runtime objects; clear activeTurn (null) instead of storing a stub","Back up the data directory before manual maintenance on session files"],"tags":["agent","turn","empty-field"],"backgroundTag":"empty-required-field","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}