-
-
Notifications
You must be signed in to change notification settings - Fork 69.4k
Matrix: 2-member rooms in groups allowlist incorrectly classified as DMs #17771
Description
Bug
When a Matrix room has exactly 2 members (e.g. bot + one user), the DM detection heuristic in extensions/matrix/src/matrix/monitor/direct.ts classifies it as a direct message, even if the room is explicitly listed in channels.matrix.groups config.
This causes the room to route to the agent's main session (agent:main:main) instead of getting its own isolated group session (agent:main:matrix:channel:<roomId>).
Steps to Reproduce
- Create a Matrix room with a name/alias (e.g.
#openclaw:server) - Invite the bot — room now has exactly 2 members
- Add the room to
channels.matrix.groupsallowlist:"groups": { "!roomId:server": { "allow": true } }
- Send a message in the room
- Observe the message routes to
agent:main:maininstead ofagent:main:matrix:channel:!roomId:server
Root Cause
In direct.ts, isDirectMessage() has three checks:
client.dms.isDm(roomId)— checksm.directaccount datamemberCount === 2— this catches all 2-person rooms regardless of configis_directstate flag
Check #2 fires before any config-awareness, so allowlisted group rooms with 2 members are always classified as DMs.
Proposed Fix
Pass the set of configured group room IDs into createDirectRoomTracker. If a room is in that set, skip all DM heuristics and return false immediately.
// direct.ts
type DirectRoomTrackerOptions = {
log?: (message: string) => void;
/** Room IDs explicitly configured as groups — never classify these as DMs. */
configuredGroupRoomIds?: ReadonlySet<string>;
};
// In isDirectMessage(), before any other checks:
if (configuredGroupRoomIds.has(roomId)) {
log(`matrix: dm check skipped — room in groups config room=${roomId}`);
return false;
}// index.ts — when creating the tracker:
const directTracker = createDirectRoomTracker(client, {
log: logVerboseMessage,
configuredGroupRoomIds: new Set(
roomsConfig ? Object.keys(roomsConfig).filter((k) => k !== "*") : [],
),
});Patch is minimal (2 files), backward compatible, and TypeScript compiles clean.
Environment
- OpenClaw 2026.2.15 (local build from main)
- Matrix plugin from
extensions/matrix - Self-hosted homeserver via Tailscale