fix(plugins): make service registration idempotent

Treat duplicate registerService calls from the same plugin id as idempotent so plugin snapshot and activation loads stop emitting spurious service already registered diagnostics.\n\nThanks @ly85206559.
This commit is contained in:
ly85206559
2026-04-10 21:06:18 +08:00
committed by GitHub
parent 03e19c5436
commit 13821fd54b
3 changed files with 35 additions and 1 deletions

View File

@@ -1519,7 +1519,7 @@ module.exports = { id: "throws-after-import", register() {} };`,
},
},
onlyPluginIds: ["internal-hook-reload"],
} as const;
};
loadOpenClawPlugins(loadOptions);
loadOpenClawPlugins(loadOptions);
@@ -2463,6 +2463,34 @@ module.exports = { id: "throws-after-import", register() {} };`,
});
});
it("allows the same plugin to register the same service id twice", () => {
useNoBundledPlugins();
const plugin = writePlugin({
id: "service-owner-self",
filename: "service-owner-self.cjs",
body: `module.exports = { id: "service-owner-self", register(api) {
api.registerService({ id: "shared-service", start() {} });
api.registerService({ id: "shared-service", start() {} });
} };`,
});
const registry = loadRegistryFromSinglePlugin({
plugin,
pluginConfig: {
allow: ["service-owner-self"],
},
});
expect(registry.services.filter((entry) => entry.service.id === "shared-service")).toHaveLength(
1,
);
expect(
registry.diagnostics.some((diag) =>
String(diag.message).includes("service already registered: shared-service"),
),
).toBe(false);
});
it("rewrites removed registerHttpHandler failures into migration diagnostics", () => {
useNoBundledPlugins();
const plugin = writePlugin({