Skip to content

fix(slack): case-insensitive channel ID matching for allowlist groupPolicy#26878

Closed
byungsker wants to merge 1 commit intoopenclaw:mainfrom
byungsker:fix/slack-allowlist-case-insensitive-channel-id-26874
Closed

fix(slack): case-insensitive channel ID matching for allowlist groupPolicy#26878
byungsker wants to merge 1 commit intoopenclaw:mainfrom
byungsker:fix/slack-allowlist-case-insensitive-channel-id-26874

Conversation

@byungsker
Copy link
Contributor

@byungsker byungsker commented Feb 25, 2026

Problem

When groupPolicy: "allowlist" is configured for Slack, channel IDs in the config are often written in lowercase (e.g. c0abc12345) but Slack delivers events with uppercase IDs (C0ABC12345). Because resolveSlackChannelConfig passed only the raw channelId to buildChannelKeyCandidates, the case-sensitive property lookup in resolveChannelEntryMatch silently failed, causing all channel events to be dropped.

DMs are unaffected (they route through dmPolicy, bypassing the channel gate).

The failure is completely silent — no warning is logged — making it very difficult to diagnose.

Root Cause

resolveSlackChannelConfig builds its candidate key list as:

buildChannelKeyCandidates(
  channelId,          // C0ABC12345 — uppercase from Slack
  `#${directName}`,
  directName,
  normalizedName,
)

None of the candidates include the lowercase form. When resolveChannelEntryMatch iterates the candidates and does Object.prototype.hasOwnProperty.call(entries, key), it never finds c0abc12345.

Fix

Add both the lowercase and uppercase variants of channelId to the candidate list. buildChannelKeyCandidates already deduplicates identical keys, so there is no overhead for IDs that are already in the canonical case.

const channelIdLower = channelId.toLowerCase();
const channelIdUpper = channelId.toUpperCase();
const candidates = buildChannelKeyCandidates(
  channelId,
  channelIdLower !== channelId ? channelIdLower : undefined,
  channelIdUpper !== channelId ? channelIdUpper : undefined,
  ...
);

Tests

Two new test cases in monitor.test.ts:

  • Config key lowercase, runtime ID uppercase (c0abc12345C0ABC12345) ✅
  • Config key uppercase, runtime ID lowercase (defensive inverse) ✅

All 22 monitor tests pass. All 238 Slack tests pass.

Fixes #26874

Greptile Summary

This PR fixes a silent bug where Slack channel events were dropped when groupPolicy: "allowlist" was configured. The issue occurred because Slack delivers channel IDs in uppercase (e.g., C0ABC12345) but users commonly write them in lowercase in their config files (e.g., c0abc12345). The case-sensitive property lookup failed silently, causing all channel events to be dropped.

The fix adds both lowercase and uppercase variants of the channelId to the candidate key list in resolveSlackChannelConfig. The buildChannelKeyCandidates function already deduplicates identical keys, so there's no performance overhead for IDs already in the canonical case.

  • Added conditional lowercase/uppercase channel ID variants to the candidate list
  • Two comprehensive test cases cover both directions (config lowercase → runtime uppercase, and the defensive inverse)
  • The fix is minimal, focused, and leverages existing deduplication logic

Confidence Score: 5/5

  • This PR is safe to merge with no risk
  • The fix is minimal, well-tested, and addresses a clear bug. The implementation leverages existing deduplication logic in buildChannelKeyCandidates, adds both case variants conditionally (only when they differ from the original), and includes comprehensive test coverage for both directions of the case mismatch. The change is isolated to the channel config resolution logic and follows established patterns in the codebase for case-insensitive matching.
  • No files require special attention

Last reviewed commit: cdd9d8d

…olicy

Slack always delivers channel IDs in uppercase (e.g. C0ABC12345) but
operators commonly write them in lowercase (c0abc12345) when copying from
docs or older tooling. resolveSlackChannelConfig passed only the raw
channelId to buildChannelKeyCandidates, so resolveChannelEntryMatch
could not find the config entry and silently dropped all channel events
when groupPolicy was 'allowlist'.

Fix: add both lowercase and uppercase variants of channelId to the
candidate list. buildChannelKeyCandidates deduplicates identical keys,
so there is no overhead for IDs that are already in the canonical case.

Two new test cases cover both directions (uppercase runtime/lowercase
config and the inverse).

Fixes openclaw#26874
steipete added a commit that referenced this pull request Feb 26, 2026
…thanks @lbo728)

Land contributor PR #26878 from @lbo728; include changelog credit and regression tests.

Co-authored-by: lbo728 <extreme0728@gmail.com>
@steipete
Copy link
Contributor

Landed on main via maintainer landing flow.

  • PR head commit (contributor): cdd9d8dd9bf1fcc325e430ff758b567376141586
  • Landing commit on main: 069bbf9740fb5349f07ed7758663fe3773084dc5
  • Temp landing commit before rebase: 4e0b2a0729339cae83c9a78b91c36d6f938e30c4

Included in landing:

  • Slack allowlist channel-ID case-insensitive matching fix
  • Regression tests (both case directions)
  • Changelog entry with PR ID and contributor credit (#26878, thanks @lbo728)
  • Co-authored-by: lbo728 <extreme0728@gmail.com> trailer on landing commit

Thanks @lbo728 for the fix and tests.

@steipete steipete closed this Feb 26, 2026
execute008 pushed a commit to execute008/openclaw that referenced this pull request Feb 27, 2026
… match (thanks @lbo728)

Land contributor PR openclaw#26878 from @lbo728; include changelog credit and regression tests.

Co-authored-by: lbo728 <extreme0728@gmail.com>
r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
… match (thanks @lbo728)

Land contributor PR openclaw#26878 from @lbo728; include changelog credit and regression tests.

Co-authored-by: lbo728 <extreme0728@gmail.com>
vincentkoc pushed a commit to Sid-Qin/openclaw that referenced this pull request Feb 28, 2026
… match (thanks @lbo728)

Land contributor PR openclaw#26878 from @lbo728; include changelog credit and regression tests.

Co-authored-by: lbo728 <extreme0728@gmail.com>
vincentkoc pushed a commit to rylena/rylen-openclaw that referenced this pull request Feb 28, 2026
… match (thanks @lbo728)

Land contributor PR openclaw#26878 from @lbo728; include changelog credit and regression tests.

Co-authored-by: lbo728 <extreme0728@gmail.com>
steipete added a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
… match (thanks @lbo728)

Land contributor PR openclaw#26878 from @lbo728; include changelog credit and regression tests.

Co-authored-by: lbo728 <extreme0728@gmail.com>
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
… match (thanks @lbo728)

Land contributor PR openclaw#26878 from @lbo728; include changelog credit and regression tests.

Co-authored-by: lbo728 <extreme0728@gmail.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
… match (thanks @lbo728)

Land contributor PR openclaw#26878 from @lbo728; include changelog credit and regression tests.

Co-authored-by: lbo728 <extreme0728@gmail.com>
thebenjaminlee pushed a commit to escape-velocity-ventures/openclaw that referenced this pull request Mar 7, 2026
… match (thanks @lbo728)

Land contributor PR openclaw#26878 from @lbo728; include changelog credit and regression tests.

Co-authored-by: lbo728 <extreme0728@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: slack Channel integration: slack size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Slack groupPolicy allowlist: case-sensitive channel ID matching silently drops all channel events

2 participants