siyuan-note/siyuan · error

invalid agent runtime turn id

Error message

invalid agent runtime turn id

What it means

Rejected by siyuan.rpc.broadcast() when the first argument is not a string (kernel/plugin/api_rpc.go:152). The broadcast target is resolved by method-name string against the RPC registry, so non-string first arguments (objects, numbers, undefined) are rejected before the params argument is inspected.

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 afa823b6b4)

Solutions

  1. Use the form broadcast(methodNameString, params)
  2. Coerce computed names: broadcast(String(name), params)
  3. Type-check before calling when the name comes from dynamic data

Example fix

// before
siyuan.rpc.broadcast({action: 'refresh'});

// after
siyuan.rpc.broadcast('myplugin.refresh', {action: 'refresh'});
Defensive patterns

Strategy: type-guard

Validate before calling

const m = typeof method === 'string' ? method : 'myplugin.notify';
siyuan.rpc.broadcast(m, params);

Type guard

const isRpcName = (v) => typeof v === 'string' && v.length > 0;

Try / catch

try { siyuan.rpc.broadcast(method, params); } catch (e) { if (/first argument must be method name string/.test(e.message)) console.error('broadcast needs the method name as arg 0, params as arg 1'); else throw e; }

Prevention

When it happens

Trigger: broadcast({type: 'notify'}) passing the payload alone; broadcast(fn) confusing broadcast with direct invocation; broadcast(methodRef.name) where methodRef is undefined.

Common situations: API confusion between broadcast(method, params) and emit(topic, data); copy-paste from siyuan.event.emit; version drift where an older snippet passed a different first-arg type.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/2222498d9cceffdb. Report an issue: GitHub.