

















@@ -1219,6 +1219,69 @@ describe("config io write", () => {
12191219});
12201220});
122112211222+it("skipPluginValidation bypasses plugin schema rejection on writeConfigFile (#76800)", async () => {
1223+await withSuiteHome(async (home) => {
1224+const configPath = path.join(home, ".openclaw", "openclaw.json");
1225+const previousConfigPath = process.env.OPENCLAW_CONFIG_PATH;
1226+process.env.OPENCLAW_CONFIG_PATH = configPath;
1227+await fs.mkdir(path.dirname(configPath), { recursive: true });
1228+await fs.writeFile(configPath, "{}\n", "utf-8");
1229+mockLoadPluginManifestRegistry.mockReturnValue({
1230+diagnostics: [],
1231+plugins: [
1232+{
1233+id: "strict-plugin",
1234+origin: "bundled",
1235+channels: [],
1236+providers: [],
1237+cliBackends: [],
1238+skills: [],
1239+hooks: [],
1240+rootDir: "/tmp/openclaw-test-strict-plugin",
1241+source: "/tmp/openclaw-test-strict-plugin/index.ts",
1242+manifestPath: "/tmp/openclaw-test-strict-plugin/openclaw.plugin.json",
1243+configSchema: {
1244+type: "object",
1245+properties: { token: { type: "string" } },
1246+required: ["token"],
1247+additionalProperties: false,
1248+},
1249+},
1250+],
1251+} satisfies PluginManifestRegistry);
1252+1253+try {
1254+// Plugin is enabled but missing required "token" — validation fails without skip.
1255+const cfg: OpenClawConfig = {
1256+agents: { list: [{ id: "main", default: true }] },
1257+plugins: { entries: { "strict-plugin": { enabled: true } } },
1258+};
1259+1260+await expect(writeConfigFile(cfg, { skipPluginValidation: true })).resolves.not.toThrow();
1261+await expect(fs.readFile(configPath, "utf-8")).resolves.toContain('"strict-plugin"');
1262+1263+await expect(writeConfigFile(cfg, { skipPluginValidation: false })).rejects.toThrow(
1264+/Config validation failed/,
1265+);
1266+await expect(
1267+writeConfigFile({ agents: { list: "not-array" } } as unknown as OpenClawConfig, {
1268+skipPluginValidation: true,
1269+}),
1270+).rejects.toThrow(/Config validation failed/);
1271+} finally {
1272+mockLoadPluginManifestRegistry.mockReturnValue({
1273+diagnostics: [],
1274+plugins: [],
1275+} satisfies PluginManifestRegistry);
1276+if (previousConfigPath === undefined) {
1277+delete process.env.OPENCLAW_CONFIG_PATH;
1278+} else {
1279+process.env.OPENCLAW_CONFIG_PATH = previousConfigPath;
1280+}
1281+}
1282+});
1283+});
1284+12221285it("preserves authored tilde paths when runtime-shaped writes hand back absolute paths", async () => {
12231286await withSuiteHome(async (home) => {
12241287const configPath = path.join(home, ".openclaw", "openclaw.json");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。