-
-
Notifications
You must be signed in to change notification settings - Fork 79.1k
bug(matrix): isStrictDirectMembership classifies 2-person rooms as DMs regardless of is_direct=false or groups[] config — requireMention silently bypassed #85017
Copy link
Copy link
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.ClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.Good issue quality with a plausible reproduction path needing some confirmation.
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.ClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.Good issue quality with a plausible reproduction path needing some confirmation.
Type
Fields
Give feedbackNo fields configured for issues without a type.
Summary
extensions/matrix/src/matrix/direct-room.tsclassifies any 2-member room (bot + 1 user) as a "strict direct room" using a pure member-count heuristic. This happens before per-room/per-group config is consulted, so:channels.matrix.groups[<roomId>]withrequireMention: trueis still treated as a DM at runtime.is_direct: falseand a name is still treated as a DM.requireMention, so the bot responds to every message in those rooms regardless of mention status.The CHANGELOG entry from #57124 ("honor explicit local
is_direct: falsefor discovered DM candidates") was a partial fix — only for inherited/discovered DM candidates, not for the runtimeisStrictDirectRoompath that drives mention/skill/session routing.Affected code
inspectMatrixDirectRoomEvidencedoes read theis_directmembership flag viahasDirectMatrixMemberFlag, but the result (memberStateFlag) is never used to negate thestrictflag — even when explicitlyfalse.isStrictDirectRoomreturns.strictdirectly without consideringis_direct: falseor local config.Reproduction (verified on 2026.5.19)
Configure OpenClaw with:
Create a Matrix room via the client API with:
{ "name": "parents", "preset": "private_chat", "is_direct": false, "initial_state": [ { "type": "m.room.encryption", "state_key": "", "content": { "algorithm": "m.megolm.v1.aes-sha2" } } ], "invite": ["@user:server"] }Invite the bot, bot joins → room has 2 members. The room has a name,
is_direct: falseon the membership events, and is explicitly in OpenClaw'sgroups[]map.From
@user:server, send a plain message (no@botmention) → bot responds despiterequireMention: true.Add a third member (any user) to the same room → restart not required, eventually
joinedMembers.length === 3soisStrictDirectMembershipreturnsfalse→requireMention: trueis now honored: plain messages ignored, only@bot ...triggers a reply.The workaround "add a third member" confirms the diagnosis: the 2-person count is the sole DM classifier.
Why this matters
The pattern "private 1:1 room with the bot that should still require mentions" is reasonable: a personal scratch room for an admin, a held-aside room before adding family/team members, an OPS room where the user wants explicit invocation. The current code makes this impossible without inviting a placeholder third user.
The deeper issue:
groups[<roomId>]config has no effect for any 2-person room. The schema'sroomsvsgroupsdistinction is silently broken for the smallest rooms.Proposed fix shape
In
isStrictDirectRoom(or its callers), treat as NOT a strict direct room when any of the following hold:m.room.memberevent hasis_direct: false(already readable viahasDirectMatrixMemberFlag— just needs to be honored as a veto, not an augmentation).room_idis explicitly listed inchannels.matrix.groups[].m.room.nameset — DMs are conventionally nameless.Suggested minimal patch in
inspectMatrixDirectRoomEvidence:Then a separate change in the channel runtime to check
groups[roomId]presence before routing through DM logic.Environment
@openclaw/matrixghcr.io/openclaw/openclaw:latestRelated
Happy to draft a PR if the maintainers concur on the fix shape — wanted to file the issue first to get the design discussion in the right place.