fix(gateway): stop shared-main chat.send from inheriting stale external routes#38418
Conversation
… channels
chat.send always originates from the webchat/control-UI surface. Previously,
channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused
OriginatingChannel to inherit the session's stored external route, so the
reply dispatcher would route responses to Slack/Telegram instead of back to
the gateway connection. Remove the route-inheritance logic from chat.send and
always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat").
Closes openclaw#34647
Made-with: Cursor
Greptile SummaryThis PR extracts the
Confidence Score: 3/5
Last reviewed commit: 0489f17 |
|
Addressed the Changes pushed:
Validation:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0f284f21b2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (params.sessionKey.length > CHAT_SEND_SESSION_KEY_MAX_LENGTH) { | ||
| return { | ||
| originatingChannel: INTERNAL_MESSAGE_CHANNEL, | ||
| explicitDeliverRoute: false, | ||
| }; |
There was a problem hiding this comment.
Remove canonical-length guard from route resolution
The new guard checks params.sessionKey.length inside resolveChatSendOriginatingRoute, but this function is called with canonicalKey from loadSessionEntry (see chat.send), not the already-validated raw request key. For legacy/non-agent keys near the 512-char limit, canonicalization prepends agent:<id>: and can push the key over CHAT_SEND_SESSION_KEY_MAX_LENGTH, causing ExplicitDeliverRoute to be forced false even when deliver: true and explicit channel scope are valid. This silently reroutes replies to webchat for long-but-valid session keys instead of preserving external delivery.
Useful? React with 👍 / 👎.
…al routes (openclaw#38418) * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes openclaw#34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber <[email protected]>
…al routes (#38418) * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes #34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber <[email protected]>
…nel-scoped sessions (openclaw#38957) When webchat/Control UI clients access channel-scoped sessions (e.g. agent:main:imessage:direct:+123), they were incorrectly inheriting the external delivery route from the session's stored context. This caused webchat messages to be tagged with channel: 'imessage' instead of channel: 'webchat', leading to cross-channel message synchronization when dmScope is set to 'per-channel-peer'. The fix adds isFromWebchatClient as a top-level condition in canInheritDeliverableRoute, ensuring webchat clients never inherit external delivery routes regardless of session type. This extends openclaw#38418 which only fixed shared-main sessions.
…al routes (openclaw#38418) * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes openclaw#34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber <[email protected]>
…al routes (openclaw#38418) * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes openclaw#34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber <[email protected]>
…al routes (openclaw#38418) * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes openclaw#34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber <[email protected]>
…al routes (openclaw#38418) * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes openclaw#34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber <[email protected]>
…al routes (openclaw#38418) * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes openclaw#34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber <[email protected]>
…al routes (openclaw#38418) * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes openclaw#34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber <[email protected]>
…al routes (openclaw#38418) * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes openclaw#34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber <[email protected]> (cherry picked from commit 563a125)
…al routes (openclaw#38418) * fix(gateway): prevent webchat messages from cross-routing to external channels chat.send always originates from the webchat/control-UI surface. Previously, channel-scoped session keys (e.g. agent:main:slack:direct:U…) caused OriginatingChannel to inherit the session's stored external route, so the reply dispatcher would route responses to Slack/Telegram instead of back to the gateway connection. Remove the route-inheritance logic from chat.send and always set OriginatingChannel to INTERNAL_MESSAGE_CHANNEL ("webchat"). Closes openclaw#34647 Made-with: Cursor * Gateway: preserve configured-main connect gating * Gateway: cover connect-without-client routing * Gateway: add chat.send session key length limit * Gateway: cap chat.send session key schema * Gateway: bound chat.send session key parsing * Gateway: cover oversized chat.send session keys * Update CHANGELOG.md --------- Co-authored-by: SidQin-cyber <[email protected]> (cherry picked from commit 563a125)
Summary
Describe the problem and fix in 2–5 bullets:
chat.sendwebchat sessions can inherit stale external delivery metadata from stored session context and route replies to the wrong channel.chat.sendroute decision into a focused helper and narrowed the fix so channel-scoped sessions still preserve explicit external delivery while shared-main/channel-agnostic webchat sessions refuse stale inherited routes.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
WebChat replies sent through shared-main or other channel-agnostic
chat.sendsessions no longer leak to stale external channels unless the session key explicitly targets that channel.Security Impact (required)
Yes/No) NoYes/No) NoYes/No) NoYes/No) NoYes/No) NoYes, explain risk + mitigation:Repro + Verification
Environment
Steps
chat.sendsession.Expected
chat.sendreplies do not inherit stale external delivery metadata.Actual
Evidence
Attach at least one:
Human Verification (required)
What you personally verified (not just CI), and how:
src/gateway/server-methods/chat.directive-tags.test.ts, typecheck, lint/format, and production dependency audit.Compatibility / Migration
Yes/No) YesYes/No) NoYes/No) NoFailure Recovery (if this breaks)
src/gateway/server-methods/chat.ts.src/gateway/server-methods/chat.ts,src/gateway/server-methods/chat.directive-tags.test.tsRisks and Mitigations
chat.sendroute selection only.