openclaw - 💡(How to fix) Fix Plugin hook ctx.channelId returns provider name instead of actual channel ID [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#59881Fetched 2026-04-08 02:39:21
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Participants

In plugin hooks (before_prompt_build, agent_end), ctx.channelId resolves to the provider name (e.g. "discord") rather than the actual channel identifier (e.g. Discord channel snowflake "1472750640760623226").

For a session key like agent:main:discord:channel:1472750640760623226:

  • ctx.channelId = "discord" (wrong — this is the provider name)
  • ctx.messageProvider = undefined (missing)
  • ctx.agentId = "main" (correct)

This causes plugins that use ctx.channelId for per-channel isolation (like Hindsight's dynamicBankGranularity) to merge all Discord channel data into a single bucket.

Root Cause

In plugin hooks (before_prompt_build, agent_end), ctx.channelId resolves to the provider name (e.g. "discord") rather than the actual channel identifier (e.g. Discord channel snowflake "1472750640760623226").

For a session key like agent:main:discord:channel:1472750640760623226:

  • ctx.channelId = "discord" (wrong — this is the provider name)
  • ctx.messageProvider = undefined (missing)
  • ctx.agentId = "main" (correct)

This causes plugins that use ctx.channelId for per-channel isolation (like Hindsight's dynamicBankGranularity) to merge all Discord channel data into a single bucket.

Code Example

[Hindsight] before_prompt_build - bank: main::discord, channel: undefined/undefined
RAW_BUFFERClick to expand / collapse

Bug: Plugin hook context ctx.channelId returns provider name instead of actual channel ID

Environment

Description

In plugin hooks (before_prompt_build, agent_end), ctx.channelId resolves to the provider name (e.g. "discord") rather than the actual channel identifier (e.g. Discord channel snowflake "1472750640760623226").

For a session key like agent:main:discord:channel:1472750640760623226:

  • ctx.channelId = "discord" (wrong — this is the provider name)
  • ctx.messageProvider = undefined (missing)
  • ctx.agentId = "main" (correct)

This causes plugins that use ctx.channelId for per-channel isolation (like Hindsight's dynamicBankGranularity) to merge all Discord channel data into a single bucket.

Debug Evidence

From Hindsight plugin debug output:

[Hindsight] before_prompt_build - bank: main::discord, channel: undefined/undefined

The plugin's deriveBankId() uses ctx?.channelId || sessionParsed.channel, but since ctx.channelId is "discord" (truthy), the session key parser fallback never fires.

Expected

  • ctx.channelId should contain the actual channel/conversation identifier (e.g. "1472750640760623226" for Discord, chat ID for Telegram, etc.)
  • ctx.messageProvider should contain the provider name (e.g. "discord", "telegram")

Impact

Any plugin relying on ctx.channelId for per-channel logic (memory isolation, per-channel settings, analytics) will incorrectly treat all channels from the same provider as one.

Session Key Reference

The session key agent:main:discord:channel:1472750640760623226 already contains the correct channel ID — the issue is that the hook context doesn't extract/expose it properly.

extent analysis

TL;DR

Update the plugin to use the session key to extract the actual channel ID, as the ctx.channelId currently returns the provider name instead of the channel identifier.

Guidance

  • Verify that the session key format is consistent and contains the channel ID, as shown in the example agent:main:discord:channel:1472750640760623226.
  • Modify the plugin's deriveBankId() function to use the session key parser fallback when ctx.channelId is equal to the provider name, to ensure the correct channel ID is used.
  • Consider adding a check to ensure ctx.messageProvider is correctly set to the provider name, to maintain consistency with the expected behavior.
  • Review other plugin hooks (before_prompt_build, agent_end) to ensure they are not relying on the incorrect ctx.channelId value.

Example

const deriveBankId = (ctx, sessionKey) => {
  const sessionParsed = parseSessionKey(sessionKey);
  const channelId = ctx.channelId === ctx.messageProvider ? sessionParsed.channel : ctx.channelId;
  // ...
};

Notes

The provided solution assumes that the session key format will remain consistent and contain the correct channel ID. If the session key format changes, the plugin will need to be updated accordingly.

Recommendation

Apply a workaround by modifying the plugin to correctly extract the channel ID from the session key, as the current ctx.channelId behavior is incorrect. This will ensure that plugins relying on per-channel logic function as expected.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Plugin hook ctx.channelId returns provider name instead of actual channel ID [1 participants]