fix(config): preserve config data when validation fails
When readConfigFileSnapshot encounters validation errors, it now: 1. Returns the resolved config data instead of empty object 2. Uses passthrough() on main schema to preserve unknown fields This prevents config loss when: - User has custom/unknown fields - Legacy config issues are detected but config is otherwise valid - Zod schema does not recognize newer fields Fixes config being overwritten with empty object on validation failure.
This commit is contained in:
committed by
Peter Steinberger
parent
b32f6a0e00
commit
20ba8d4891
@@ -1685,3 +1685,46 @@ describe("multi-agent agentDir validation", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("config preservation on validation failure", () => {
|
||||
it("preserves unknown fields via passthrough", async () => {
|
||||
vi.resetModules();
|
||||
const { validateConfigObject } = await import("./config.js");
|
||||
const res = validateConfigObject({
|
||||
agents: { list: [{ id: "pi" }] },
|
||||
customUnknownField: { nested: "value" },
|
||||
});
|
||||
expect(res.ok).toBe(true);
|
||||
expect(
|
||||
(res as { config: Record<string, unknown> }).config.customUnknownField,
|
||||
).toEqual({
|
||||
nested: "value",
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves config data when validation fails", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const configDir = path.join(home, ".clawdbot");
|
||||
await fs.mkdir(configDir, { recursive: true });
|
||||
await fs.writeFile(
|
||||
path.join(configDir, "clawdbot.json"),
|
||||
JSON.stringify({
|
||||
agents: { list: [{ id: "pi" }] },
|
||||
routing: { allowFrom: ["+15555550123"] },
|
||||
customData: { preserved: true },
|
||||
}),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
vi.resetModules();
|
||||
const { readConfigFileSnapshot } = await import("./config.js");
|
||||
const snap = await readConfigFileSnapshot();
|
||||
|
||||
expect(snap.valid).toBe(false);
|
||||
expect(snap.legacyIssues.length).toBeGreaterThan(0);
|
||||
expect((snap.config as Record<string, unknown>).customData).toEqual({
|
||||
preserved: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -296,7 +296,7 @@ export function createConfigIO(overrides: ConfigIoDeps = {}) {
|
||||
raw,
|
||||
parsed: parsedRes.parsed,
|
||||
valid: false,
|
||||
config: {},
|
||||
config: resolved as ClawdbotConfig,
|
||||
issues: validated.issues,
|
||||
legacyIssues,
|
||||
};
|
||||
|
||||
@@ -1757,6 +1757,7 @@ export const ClawdbotSchema = z
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.passthrough()
|
||||
.superRefine((cfg, ctx) => {
|
||||
const agents = cfg.agents?.list ?? [];
|
||||
if (agents.length === 0) return;
|
||||
|
||||
Reference in New Issue
Block a user