← Back to PRs

#17579: fix(slack): prevent Zod default groupPolicy from breaking multi-account config

by ZetiMente open 2026-02-15 23:03 View on GitHub →
stale size: XS
## Summary - **Moves `.default("allowlist")` from `SlackAccountSchema` to `SlackConfigSchema`** so Zod only injects the default at the top-level config, not into individual account entries. - Fixes multi-account Slack configs silently dropping all channel messages (DMs still worked, @mentions in channels did not). ## Root Cause `SlackAccountSchema` has `groupPolicy: GroupPolicySchema.optional().default("allowlist")`. When Zod parses an account entry like `{ botToken: "...", appToken: "..." }`, it injects `groupPolicy: "allowlist"` into the output — even though the user never specified it. `mergeSlackAccountConfig` then does `{ ...base, ...account }`, so the account's phantom `"allowlist"` overrides the user's top-level `groupPolicy: "open"`. With `"allowlist"` active and no channels explicitly listed, `isSlackChannelAllowedByPolicy` returns `false` for every channel message. This affects **any** config that uses the `channels.slack.accounts` object, even with a single account. The developer's intent was probably "default to secure" — which is reasonable. The mistake was putting that default on the account schema instead of the top-level schema. The right place for "default to secure if nobody says anything" is SlackConfigSchema, because that's the one that represents the user's actual top-level config. Individual account entries are meant to inherit from that, and Zod defaults break the inheritance by filling in keys that should have stayed undefined. ## The Fix ```diff - // SlackAccountSchema - groupPolicy: GroupPolicySchema.optional().default("allowlist"), + // SlackAccountSchema — no default, so accounts don't poison the merge + groupPolicy: GroupPolicySchema.optional(), // SlackConfigSchema.safeExtend — default lives here now + groupPolicy: GroupPolicySchema.optional().default("allowlist"), ``` ## Test Plan - [x] All 149 existing Slack tests pass (`pnpm test -- --grep slack`) - [x] Live-tested on Raspberry Pi running OpenClaw v2026.2.14 with two Slack bot accounts in socket mode - [x] Confirmed DMs work for both accounts - [x] Confirmed @mentions in channels work for both accounts - [x] Confirmed non-mentioned messages in channels are correctly skipped - [x] Single-account top-level config (no `accounts` object) continues to work as before Fixes #17507 Related: #5626, #16522 cc @thewilloftheshadow (Slack subsystem) @gumadeiras (multi-agent) --- 🤖 **AI-assisted:** This bug was diagnosed and fixed by Claude Opus 4.6 (Anthropic) in a live demo session with @ZetiMente. Fully tested on a live instance. <!-- greptile_comment --> <h3>Greptile Summary</h3> Fixes a bug where Zod's `.default("allowlist")` on `SlackAccountSchema.groupPolicy` caused a phantom default to be injected into every parsed account entry, overriding the user's top-level `groupPolicy` during the shallow merge (`{ ...base, ...account }`) in `mergeSlackAccountConfig`. This silently broke channel message delivery for multi-account Slack configs. - Removed `.default("allowlist")` from `SlackAccountSchema` so account entries no longer get a phantom `groupPolicy` injected - Added `.default("allowlist")` to `SlackConfigSchema` via `safeExtend` so the secure default still applies at the top-level config - **The same bug pattern exists in other providers** (Discord, Telegram, Signal, IRC, iMessage, BlueBubbles) — all have `.default("allowlist")` on their account schemas and use the same shallow merge, but were not addressed in this PR <h3>Confidence Score: 4/5</h3> - The Slack fix is correct and safe to merge, though the same bug exists in other providers. - The change is minimal, well-reasoned, and correctly fixes the Slack-specific issue. The author reports all 149 existing tests pass and the fix was live-tested. Deducting a point because the same Zod default-on-account-schema bug is present in 6 other providers (Discord, Telegram, Signal, IRC, iMessage, BlueBubbles) that use the identical merge pattern, and this PR does not address them. - Other account schemas in `src/config/zod-schema.providers-core.ts` (DiscordAccountSchema line 275, TelegramAccountSchemaBase line 108, SignalAccountSchemaBase line 657, IrcAccountSchemaBase line 745, IMessageAccountSchemaBase line 805, BlueBubblesAccountSchemaBase line 897) have the same latent bug. <sub>Last reviewed commit: fc243e3</sub> <!-- greptile_other_comments_section --> <sub>(1/5) You can manually trigger the agent by mentioning @greptileai in a comment!</sub> <!-- /greptile_comment -->

Most Similar PRs