-
Notifications
You must be signed in to change notification settings - Fork 399
OpenClaw plugin: ctx.channelId returns provider name instead of channel ID for Discord sessions #854
Description
Bug: ctx.channelId returns provider name instead of actual channel ID for Discord sessions
Environment
- OpenClaw version: 2026.4.1
- Hindsight plugin:
@vectorize-io/hindsight-openclaw@0.4.19 - Channel: Discord
- Config:
dynamicBankGranularity: ["agent", "channel"]
Expected Behavior
With dynamicBankGranularity: ["agent", "channel"], Discord channel memories should be isolated per-channel. For a session key like agent:main:discord:channel:1472750640760623226, the bank ID should resolve to something like main::channel:1472750640760623226 (or ideally the channel name like main::morpheus).
Actual Behavior
All Discord memories go to a single bank main::discord regardless of which channel the conversation is in.
Root Cause
In deriveBankId(), the field map uses:
channel: ctx?.channelId || sessionParsed.channel || 'unknown'The ctx.channelId value is "discord" (the provider/channel type name) rather than the actual Discord channel ID (e.g. 1472750640760623226). Since ctx.channelId has priority over the session key parser fallback, the bank always resolves to main::discord.
Debug output confirms:
[Hindsight] before_prompt_build - bank: main::discord, channel: undefined/undefined
(Note: ctx.messageProvider is also undefined in some hook contexts)
The parseSessionKey() fallback would correctly extract channel:1472750640760623226 from the session key, but it never gets used because ctx.channelId is truthy (it's "discord").
Workaround Attempted
None found within plugin config. The issue appears to be upstream — OpenClaw's hook context populates ctx.channelId with the provider name rather than the Discord channel snowflake ID.
Suggested Fix
- In OpenClaw core: Populate
ctx.channelIdwith the actual channel/conversation identifier (e.g. the Discord channel snowflake) rather than the provider name. - In the plugin (defensive): If
ctx.channelIdmatches a known provider name (discord, telegram, slack, etc.), treat it as missing and fall through to thesessionParsed.channelfallback.
Impact
- All Discord channel memories merge into one bank, defeating per-channel isolation
- Users who configure
dynamicBankGranularitywith"channel"get no benefit on Discord - Likely affects other multi-channel providers too (Telegram groups, Slack channels)