From 3c9437ae547acd2b26231dac30535e3d90fd7280 Mon Sep 17 00:00:00 2001 From: "clawsweeper[bot]" <274271284+clawsweeper[bot]@users.noreply.github.com> Date: Wed, 29 Apr 2026 22:34:59 -0700 Subject: [PATCH] fix: configs that used the previously documented WhatsApp exposeErrorText key now fail valida... (#74667) * fix: configs that used the previously documented WhatsApp exposeErrorText key now fail valida... * fix(clawsweeper): address review for clawsweeper-commit-openclaw-openclaw-4cba08df01ea (1) --------- Co-authored-by: openclaw-clawsweeper[bot] <280122609+openclaw-clawsweeper[bot]@users.noreply.github.com> --- .../zod-schema.providers-whatsapp.test.ts | 40 +++++++++++++++++++ src/config/zod-schema.providers-whatsapp.ts | 26 +++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/config/zod-schema.providers-whatsapp.test.ts b/src/config/zod-schema.providers-whatsapp.test.ts index d45b9a93378..fab8510c2d4 100644 --- a/src/config/zod-schema.providers-whatsapp.test.ts +++ b/src/config/zod-schema.providers-whatsapp.test.ts @@ -96,4 +96,44 @@ describe("WhatsApp prompt config Zod validation", () => { expect(result.data.direct?.["+15557654321"]?.systemPrompt).toBe("Keep responses concise"); } }); + + it("accepts deprecated exposeErrorText as a no-op compatibility key", () => { + const result = WhatsAppConfigSchema.safeParse({ + exposeErrorText: false, + accounts: { + work: { + exposeErrorText: true, + }, + }, + }); + + expect(result.success).toBe(true); + if (result.success) { + expect(Object.hasOwn(result.data, "exposeErrorText")).toBe(false); + expect(Object.hasOwn(result.data.accounts?.work ?? {}, "exposeErrorText")).toBe(false); + } + }); + + it("keeps deprecated exposeErrorText out of generated config surfaces", () => { + const schema = WhatsAppConfigSchema.toJSONSchema({ + target: "draft-07", + unrepresentable: "any", + }) as { + properties?: { + exposeErrorText?: unknown; + accounts?: { + additionalProperties?: { + properties?: { + exposeErrorText?: unknown; + }; + }; + }; + }; + }; + + expect(schema.properties?.exposeErrorText).toBeUndefined(); + expect(schema.properties?.accounts?.additionalProperties?.properties?.exposeErrorText).toBe( + undefined, + ); + }); }); diff --git a/src/config/zod-schema.providers-whatsapp.ts b/src/config/zod-schema.providers-whatsapp.ts index f1b1fb0516b..08d9c5aa774 100644 --- a/src/config/zod-schema.providers-whatsapp.ts +++ b/src/config/zod-schema.providers-whatsapp.ts @@ -48,6 +48,18 @@ const WhatsAppAckReactionSchema = z .strict() .optional(); +function stripDeprecatedWhatsAppNoopKeys(value: unknown): unknown { + if (!value || typeof value !== "object" || Array.isArray(value)) { + return value; + } + if (!Object.hasOwn(value, "exposeErrorText")) { + return value; + } + const next = { ...(value as Record) }; + delete next.exposeErrorText; + return next; +} + function buildWhatsAppCommonShape(params: { useDefaults: boolean }) { return { enabled: z.boolean().optional(), @@ -130,7 +142,7 @@ function enforceAllowlistDmPolicyAllowFrom(params: { }); } -export const WhatsAppAccountSchema = z +const WhatsAppAccountObjectSchema = z .object({ ...buildWhatsAppCommonShape({ useDefaults: false }), name: z.string().optional(), @@ -141,7 +153,12 @@ export const WhatsAppAccountSchema = z }) .strict(); -export const WhatsAppConfigSchema = z +export const WhatsAppAccountSchema = z.preprocess( + stripDeprecatedWhatsAppNoopKeys, + WhatsAppAccountObjectSchema, +); + +const WhatsAppConfigObjectSchema = z .object({ ...buildWhatsAppCommonShape({ useDefaults: true }), accounts: z.record(z.string(), WhatsAppAccountSchema.optional()).optional(), @@ -206,3 +223,8 @@ export const WhatsAppConfigSchema = z }); } }); + +export const WhatsAppConfigSchema = z.preprocess( + stripDeprecatedWhatsAppNoopKeys, + WhatsAppConfigObjectSchema, +);