fix(plugins): validate setup runtime entry ids

This commit is contained in:
Gustavo Madeira Santana
2026-04-15 10:55:55 -04:00
parent 4afd460695
commit 9992c76349
2 changed files with 15 additions and 3 deletions

View File

@@ -3590,7 +3590,8 @@ module.exports = {
);
});
it("rejects mismatched bundled runtime plugin ids during setup-runtime merge", () => {
it("rejects mismatched bundled runtime entry ids before applying setup-runtime setters", () => {
const runtimeMarker = path.join(makeTempDir(), "setup-runtime-mismatch.txt");
const built = createSetupEntryChannelPluginFixture({
id: "setup-runtime-mismatch-test",
bundledFullEntryId: "wrong-runtime-id",
@@ -3601,7 +3602,7 @@ module.exports = {
configured: false,
useBundledFullEntryContract: true,
useBundledSetupEntryContract: true,
bundledFullRuntimeMarker: path.join(makeTempDir(), "setup-runtime-mismatch.txt"),
bundledFullRuntimeMarker: runtimeMarker,
});
const registry = loadOpenClawPlugins({
@@ -3619,8 +3620,9 @@ module.exports = {
).toBe("error");
expect(
registry.plugins.find((entry) => entry.id === "setup-runtime-mismatch-test")?.error,
).toContain('runtime export uses "wrong-runtime-id"');
).toContain('runtime entry uses "wrong-runtime-id"');
expect(registry.channels).toHaveLength(0);
expect(fs.existsSync(runtimeMarker)).toBe(false);
});
it("isolates loadSetupPlugin errors as per-plugin diagnostics instead of crashing registry load", () => {

View File

@@ -684,6 +684,7 @@ function mergeSetupRuntimeChannelPlugin(
}
function resolveBundledRuntimeChannelRegistration(moduleExport: unknown): {
id?: string;
loadChannelPlugin?: () => ChannelPlugin;
loadChannelSecrets?: () => ChannelPlugin["secrets"] | undefined;
setChannelRuntime?: (runtime: PluginRuntime) => void;
@@ -694,17 +695,20 @@ function resolveBundledRuntimeChannelRegistration(moduleExport: unknown): {
}
const entryRecord = resolved as {
kind?: unknown;
id?: unknown;
loadChannelPlugin?: unknown;
loadChannelSecrets?: unknown;
setChannelRuntime?: unknown;
};
if (
entryRecord.kind !== "bundled-channel-entry" ||
typeof entryRecord.id !== "string" ||
typeof entryRecord.loadChannelPlugin !== "function"
) {
return {};
}
return {
id: entryRecord.id,
loadChannelPlugin: entryRecord.loadChannelPlugin as () => ChannelPlugin,
...(typeof entryRecord.loadChannelSecrets === "function"
? {
@@ -1850,6 +1854,12 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
continue;
}
const runtimeRegistration = resolveBundledRuntimeChannelRegistration(runtimeMod);
if (runtimeRegistration.id && runtimeRegistration.id !== record.id) {
pushPluginLoadError(
`plugin id mismatch (config uses "${record.id}", runtime entry uses "${runtimeRegistration.id}")`,
);
continue;
}
if (runtimeRegistration.setChannelRuntime) {
try {
runtimeRegistration.setChannelRuntime(api.runtime);