siyuan-note/siyuan · error
invalid agent runtime turn
Error message
invalid agent runtime turn
What it means
beginRuntimeTurn requires the turn argument to carry a non-empty TurnID and to be in the "running" state. This error means the turn passed in is structurally invalid as a turn to begin — it either lacks an identifier or is not entering the running state, so recording it as the session's ActiveTurn would be meaningless.
Solutions
- Set turn.TurnID to a fresh unique identifier before calling beginRuntimeTurn
- Ensure turn.State is exactly "running" when beginning; handle finished/interrupted turns through their own code paths
- Use the public turn-start APIs rather than assembling agentRuntimeTurn manually
Example fix
// before
turn := &agentRuntimeTurn{State: "finished"}
beginRuntimeTurn(sessionID, turn)
// after
turn := &agentRuntimeTurn{TurnID: newTurnID(), State: "running"}
beginRuntimeTurn(sessionID, turn) Defensive patterns
Strategy: validation
Validate before calling
if (!turn.turnID) throw new Error("turnID is required before beginRuntimeTurn");
if (turn.state !== "running") throw new Error(`cannot begin a turn in state ${turn.state}`); Type guard
function isBeginnableTurn(t: AgentRuntimeTurn): boolean { return typeof t.turnID === "string" && t.turnID !== "" && t.state === "running"; } Prevention
- Generate a fresh TurnID for every new turn and set state to "running" before beginning
- Route finished/interrupted turns to completion APIs, never back through begin
- Construct turns through a single factory function that enforces these invariants
When it happens
Trigger: Calling beginRuntimeTurn with a turn whose TurnID is "" or whose State is anything other than "running" (e.g. building a finished/interrupted turn and passing it to begin instead of the appropriate completion path).
Common situations: Constructing agentRuntimeTurn by hand and forgetting to set TurnID; reusing a completed turn object for a new begin call; a state machine bug that marks the turn finished before beginning it.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- agent runtime user entry not found
- agent session has an uncommitted turn
- capability was not exposed in this model round
- frontend capability description is required
- image MIME type is missing
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/89e0c0e8ea399221.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/agent/runtime.go:257
runtime.SchemaVersion = 1
runtime.SessionID = sessionID
runtime.Revision++
data, err := gulu.JSON.MarshalIndentJSON(runtime, "", "\t")
if err != nil {
return err
}
return filelock.WriteFile(runtimePath(sessionID), data)
}
func beginRuntimeTurn(sessionID string, turn *agentRuntimeTurn) error {
if sessionID == "" || turn == nil {
return nil
}
if !isValidSessionID(sessionID) {
return fmt.Errorf("invalid session id")
}
if turn.TurnID == "" || turn.State != "running" {
return fmt.Errorf("invalid agent runtime turn")
}
lock := sessionLock(sessionID)
lock.Lock()
defer lock.Unlock()
runtime, err := loadRuntimeLocked(sessionID)
if err != nil {
return err
}
if runtime.ActiveTurn != nil && runtime.ActiveTurn.TurnID != turn.TurnID {
committed, err := isTurnCommittedLocked(sessionID, runtime.ActiveTurn.TurnID)
if err != nil {
return err
}
if !committed {
return fmt.Errorf("agent session has an uncommitted turn")
}
runtime.ActiveTurn = nil
}View on GitHub (pinned to 9f775e8a12)