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

  1. Correct the state to one of running, finished, or interrupted in the runtime file (prefer finished/interrupted to avoid resuming)
  2. Restore the runtime file from a backup made by a compatible kernel version
  3. 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

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


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 err

View on GitHub (pinned to 9f775e8a12)