siyuan-note/siyuan · error
Plugin lifecycle has ended
Error message
Plugin lifecycle has ended
What it means
KernelPluginClient #fetchRpc precondition: an RPC request was attempted after this plugin client was destroyed (#destroyed flag set). The plugin's lifecycle has ended, so no further JSON-RPC calls over api/plugin/rpc are accepted; re-checked inside the retry loop so in-flight requests abort too.
Source
Thrown at app/src/plugin/kernel.ts:169
});
}
}
});
return ws;
}
#createJsonRpcCallUrl() {
const searchParams = new URLSearchParams({ name: this.#name, appId: this.#appId });
return `api/plugin/rpc?${searchParams.toString()}`;
}
#generateId(): TJsonRpcId {
return Lute.NewNodeID();
}
async #fetchRpc(body: string): Promise<any> {
if (this.#destroyed) {
throw new Error("Plugin lifecycle has ended");
}
for (let retry = 0; ; retry++) {
if (this.#destroyed) {
throw new Error("Plugin lifecycle has ended");
}
const response = await fetch(this.#rpcCallUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body,
});
if (response.status === 204) {
return;
}
const data = await response.json();
const code = data.error?.code;
if ((code !== -32001 && code !== -32002) || retry >= KERNEL_PLUGIN_START_RETRY_COUNT) {
return data;View on GitHub (pinned to 8641553a1f)
Solutions
- Stop issuing RPC calls after plugin unload/disable
- Propagate the rejection so pending promises settle instead of retrying
- Re-enable the plugin to obtain a fresh, non-destroyed client
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at app/src/plugin/kernel.ts:169 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/6874b94eb515f031.
Report an issue: GitHub.