{"record":{"id":"2222498d9cceffdb","repo":"siyuan-note/siyuan","slug":"invalid-agent-runtime-turn-id","errorCode":null,"errorMessage":"invalid agent runtime turn id","messagePattern":"invalid agent runtime turn id","errorType":"http","errorClass":null,"httpStatus":200,"severity":"error","filePath":"kernel/agent/runtime.go","lineNumber":214,"sourceCode":"\t\t}\n\t\treturn nil, err\n\t}\n\tvar runtime agentRuntime\n\tif err := gulu.JSON.UnmarshalJSON(data, &runtime); err != nil {\n\t\treturn nil, err\n\t}\n\tif runtime.SchemaVersion > 1 {\n\t\treturn nil, fmt.Errorf(\"unsupported agent runtime schema version: %d\", runtime.SchemaVersion)\n\t}\n\tif runtime.SessionID != \"\" && runtime.SessionID != sessionID {\n\t\treturn nil, fmt.Errorf(\"agent runtime session id mismatch\")\n\t}\n\tif runtime.Revision < 0 {\n\t\treturn nil, fmt.Errorf(\"invalid agent runtime revision\")\n\t}\n\tif runtime.ActiveTurn != nil {\n\t\tif runtime.ActiveTurn.TurnID == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"invalid agent runtime turn id\")\n\t\t}\n\t\tswitch runtime.ActiveTurn.State {\n\t\tcase \"running\", \"finished\", \"interrupted\":\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"invalid agent runtime turn state\")\n\t\t}\n\t}\n\tif runtime.SchemaVersion == 0 {\n\t\truntime.SchemaVersion = 1\n\t}\n\tif runtime.SessionID == \"\" {\n\t\truntime.SessionID = sessionID\n\t}\n\treturn &runtime, nil\n}\n\nfunc writeRuntimeLocked(sessionID string, runtime *agentRuntime) error {\n\tif runtime == nil {","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/afa823b6b4e4f183511e0bc0a3be93caa94c7c97/kernel/agent/runtime.go#L196-L232","documentation":"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.","triggerScenarios":"broadcast({type: 'notify'}) passing the payload alone; broadcast(fn) confusing broadcast with direct invocation; broadcast(methodRef.name) where methodRef is undefined.","commonSituations":"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.","solutions":["Use the form broadcast(methodNameString, params)","Coerce computed names: broadcast(String(name), params)","Type-check before calling when the name comes from dynamic data"],"exampleFix":"// before\nsiyuan.rpc.broadcast({action: 'refresh'});\n\n// after\nsiyuan.rpc.broadcast('myplugin.refresh', {action: 'refresh'});","handlingStrategy":"type-guard","validationCode":"const m = typeof method === 'string' ? method : 'myplugin.notify';\nsiyuan.rpc.broadcast(m, params);","typeGuard":"const isRpcName = (v) => typeof v === 'string' && v.length > 0;","tryCatchPattern":"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; }","preventionTips":["Do not confuse broadcast(method, params) with event.emit(topic, data) argument shapes","String()-coerce dynamic method names","Type-check names coming from user or config data"],"tags":["rpc","plugin-api","type-validation","siyuan"],"backgroundTag":"invalid-argument-type","analyzedSha":"afa823b6b4e4f183511e0bc0a3be93caa94c7c97","analyzedAt":"2026-08-18T17:04:10.865Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}