fix(matrix): preserve case in group/channel peer IDs for session keys#57337
fix(matrix): preserve case in group/channel peer IDs for session keys#57337dlardo wants to merge 1 commit into
Conversation
Greptile SummaryThis PR fixes a critical crash-loop bug in the Matrix gateway by removing the
Confidence Score: 4/5Safe to merge after addressing the residual The core fix is correct and well-tested. However, the sibling
|
| Filename | Overview |
|---|---|
| src/routing/session-key.ts | Removes .toLowerCase() from the non-direct peer ID path in buildAgentPeerSessionKey, correctly preserving Matrix room ID case for session keys. However, the sibling buildGroupHistoryKey function still lowercases its peerId, creating a case inconsistency between session keys and history keys for the same Matrix room. |
| src/routing/session-key.continuity.test.ts | Adds two tests verifying that mixed-case Matrix room IDs are preserved verbatim in both channel and group session keys. Tests are correct and cover the exact regression scenario described in the PR. |
Comments Outside Diff (1)
-
src/routing/session-key.ts, line 230 (link)buildGroupHistoryKeystill lowercasespeerIdbuildGroupHistoryKeyat line 230 still calls.toLowerCase()onpeerId, applying the same case-mangling to Matrix room IDs that this PR fixes inbuildAgentPeerSessionKey.This creates an immediate inconsistency: after this fix, the session key for a Matrix group room like
!IEjZDNPucuFvKLrAQC:serverwill use the original-case ID (correct), but any history key built for the same room viabuildGroupHistoryKeywill still be lowercased. Any code that joins or correlates session keys with history keys for Matrix rooms will therefore fail to match across the two.Prompt To Fix With AI
This is a comment left during a code review. Path: src/routing/session-key.ts Line: 230 Comment: **`buildGroupHistoryKey` still lowercases `peerId`** `buildGroupHistoryKey` at line 230 still calls `.toLowerCase()` on `peerId`, applying the same case-mangling to Matrix room IDs that this PR fixes in `buildAgentPeerSessionKey`. This creates an immediate inconsistency: after this fix, the session key for a Matrix group room like `!IEjZDNPucuFvKLrAQC:server` will use the original-case ID (correct), but any history key built for the same room via `buildGroupHistoryKey` will still be lowercased. Any code that joins or correlates session keys with history keys for Matrix rooms will therefore fail to match across the two. How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/routing/session-key.ts
Line: 230
Comment:
**`buildGroupHistoryKey` still lowercases `peerId`**
`buildGroupHistoryKey` at line 230 still calls `.toLowerCase()` on `peerId`, applying the same case-mangling to Matrix room IDs that this PR fixes in `buildAgentPeerSessionKey`.
This creates an immediate inconsistency: after this fix, the session key for a Matrix group room like `!IEjZDNPucuFvKLrAQC:server` will use the original-case ID (correct), but any history key built for the same room via `buildGroupHistoryKey` will still be lowercased. Any code that joins or correlates session keys with history keys for Matrix rooms will therefore fail to match across the two.
```suggestion
const peerId = params.peerId.trim() || "unknown";
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(matrix): preserve case in group/chan..." | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fa46acf21d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| @@ -169,7 +169,7 @@ export function buildAgentPeerSessionKey(params: { | |||
| }); | |||
| } | |||
| const channel = (params.channel ?? "").trim().toLowerCase() || "unknown"; | |||
| const peerId = ((params.peerId ?? "").trim() || "unknown").toLowerCase(); | |||
| const peerId = (params.peerId ?? "").trim() || "unknown"; | |||
There was a problem hiding this comment.
Scope case-preserving IDs to Matrix peers only
Removing .toLowerCase() here changes canonicalization for all non-direct peers, not just Matrix room IDs. That means channels with case-insensitive identifiers (for example Slack C123/G123) can now generate different session keys for the same conversation based on input casing, while other flows still canonicalize via lowercasing (see toAgentStoreSessionKey in src/routing/session-key.ts). The result is split/orphaned session state and inconsistent lookups/recovery when a key is rebuilt with different case. Please gate case-preservation to Matrix room/group peers and keep prior lowercase normalization for other providers.
Useful? React with 👍 / 👎.
7253a17 to
45b8d96
Compare
Matrix room IDs are case-sensitive opaque identifiers per the spec. The previous toLowerCase() on group/channel peer IDs caused delivery- recovery to use a lowercased room ID that Synapse rejects with 403, permanently crashing the Matrix sync loop on gateway restart. Fixes openclaw#57321 Related: openclaw#19278
45b8d96 to
9eea474
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9eea474cb8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // Other providers (Slack, Discord, etc.) use case-insensitive IDs and | ||
| // must continue to be lowercased for consistent session key lookups. | ||
| const rawPeerId = (params.peerId ?? "").trim() || "unknown"; | ||
| const peerId = channel === "matrix" ? rawPeerId : rawPeerId.toLowerCase(); |
There was a problem hiding this comment.
Keep Matrix session-key casing consistent across store reads/writes
Preserving case in buildAgentPeerSessionKey for Matrix group/channel peers introduces a key-format split with existing session-store paths that still lowercase keys (src/channels/session.ts normalizes sessionKey to lowercase before recordSessionMetaFromInbound, and src/config/sessions/store.ts resolves/deletes case variants into the lowercase key), while session init still does an exact lookup via sessionStore[sessionKey] (src/auto-reply/reply/session.ts). For Matrix rooms whose IDs contain uppercase characters, this causes the mixed-case key produced here to diverge from the persisted lowercase key, so continuity lookups miss and the conversation can repeatedly start fresh/new-session instead of reusing prior context.
Useful? React with 👍 / 👎.
|
Thank you for the fix attempt here. I am not merging this as-is. Why:
So this needs a broader Matrix-safe session-key strategy, not just a local builder change. Thank you for pushing on a real problem and for adding the continuity tests. The linked issue remains valid: #57321 |
|
Closing in favor of a more targeted approach. As @vincentkoc correctly noted, fixing case normalization in the session key builders without addressing the store/persistence layer would create split session identity. New PR incoming with a narrower fix: treating the Matrix "User not in room" 403 as a permanent delivery error so delivery-recovery moves the poisoned entry to failed/ immediately instead of crash-looping the sync. This prevents the catastrophic failure while the broader case-normalization strategy is worked out separately. |
Summary
Matrix room IDs (e.g.
!IEjZDNPucuFvKLrAQC:server) are case-sensitive opaque identifiers per the Matrix spec. ThebuildAgentPeerSessionKey()function was calling.toLowerCase()on group/channel peer IDs, which destroyed the original case.This caused a critical failure path:
"to"targetdelivery-recoveryretries the send using the lowercased room IDM_FORBIDDEN: User not in room)Changes
src/routing/session-key.ts: Remove.toLowerCase()from the group/channel peer ID path inbuildAgentPeerSessionKey(). Direct/DM peer IDs still lowercase (Matrix user IDs are case-insensitive).src/routing/session-key.continuity.test.ts: Add tests verifying mixed-case room IDs are preserved in session keys.Testing
Breaking change note
Existing Matrix group/channel session keys were lowercased. After this change, new sessions will use the original-case room ID, creating new session keys. Existing lowercased sessions will become orphaned. This is acceptable since group chat sessions are ephemeral and regularly compacted/reset.
Fixes #57321
Related: #19278, PR #31023