siyuan-note/siyuan · error
invalid agent runtime turn state
Error message
invalid agent runtime turn state
What it means
loadRuntimeLocked validates the ActiveTurn.State against the fixed set "running", "finished", "interrupted". Any other string means the persisted turn state is outside the known state machine, so the runtime cannot be safely resumed.
Solutions
- Correct the state to one of running, finished, or interrupted in the runtime file (prefer finished/interrupted to avoid resuming)
- Restore the runtime file from a backup made by a compatible kernel version
- Align all kernel installations to the same version so the state vocabulary matches
Example fix
// before (runtime JSON)
"activeTurn": {"turnID": "t1", "state": "in-progress"}
// after
"activeTurn": {"turnID": "t1", "state": "interrupted"} Defensive patterns
Strategy: validation
Validate before calling
const TURN_STATES = new Set(["running", "finished", "interrupted"]);
if (runtime.activeTurn && !TURN_STATES.has(runtime.activeTurn.state)) throw new Error(`unknown turn state: ${runtime.activeTurn.state}`); Type guard
function isTurnState(s: unknown): s is TurnState { return s === "running" || s === "finished" || s === "interrupted"; } Prevention
- Model turn state as an enum in client code so invalid values cannot be written
- Match the kernel version when syncing workspaces so the state vocabulary agrees
- On mismatch, map unknown states to "interrupted" during migration
When it happens
Trigger: Loading a session whose runtime JSON has activeTurn.state equal to something other than running/finished/interrupted (e.g. "pending", "done", wrong casing, empty); a runtime file written by a different or newer kernel build with an extended state vocabulary.
Common situations: Downgraded or mismatched kernel versions; manual edits; a bug in code that writes turn state without going through the state machine.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- agent session has an uncommitted turn
- agent compaction summary is empty
- agent context cannot be compacted enough
- agent context cannot be compacted enough: build runtime…
- agent context cannot be compacted enough: build summary…
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/469c7213e873dfab.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/agent/runtime.go:219
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 {
runtime.SchemaVersion = 1
}
if runtime.SessionID == "" {
runtime.SessionID = sessionID
}
return &runtime, nil
}
func writeRuntimeLocked(sessionID string, runtime *agentRuntime) error {
if runtime == nil {
return nil
}
// runtime 只能附着在已经存在的会话上,避免迟到的 checkpoint 复活已删除会话。
if _, err := os.Stat(filepath.Join(sessionsDir(), sessionID, "session.json")); err != nil {
return errView on GitHub (pinned to 9f775e8a12)