siyuan-note/siyuan · error

invalid agent runtime turn id

Error message

invalid agent runtime turn id

What it means

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.

Solutions

  1. Set the active turn's turnID to the real turn identifier, or remove the activeTurn object entirely if no turn is in flight
  2. Restore the runtime file from workspace backup
  3. Let the kernel regenerate the runtime by clearing the session's runtime state if recovery is acceptable

Example fix

// before (runtime JSON)
"activeTurn": {"turnID": "", "state": "running"}
// after
"activeTurn": null
Defensive patterns

Strategy: validation

Validate before calling

const runtime = JSON.parse(readRuntimeFile(sessionDir));
if (runtime.activeTurn && !runtime.activeTurn.turnID) throw new Error("activeTurn missing turnID");

Type guard

function hasValidActiveTurn(r: Runtime): boolean { return r.activeTurn == null || (typeof r.activeTurn.turnID === "string" && r.activeTurn.turnID !== ""); }

Prevention

When it happens

Trigger: 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.

Common situations: Corruption from an interrupted write combined with a non-atomic file replacement; manual editing; a third-party tool modifying session state.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/2222498d9cceffdb. Report an issue: GitHub.

Appendix: source

Thrown at kernel/agent/runtime.go:214

		}
		return nil, err
	}
	var runtime agentRuntime
	if err := gulu.JSON.UnmarshalJSON(data, &runtime); err != nil {
		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 {

View on GitHub (pinned to 9f775e8a12)