Skip to content

[Bug]: Matrix plugin treats 2-member rooms as DMs even when explicitly configured in groups #20145

@squirblej

Description

@squirblej

Summary

Rooms with exactly 2 members (bot + one user) that are explicitly listed in channels.matrix.groups config are still classified as direct messages by directTracker.isDirectMessage(). Messages route to the main DM session instead of getting an isolated group session.

Steps to reproduce

  1. Create a Matrix room with only the bot and one user (2 members total)
  2. Add the room to channels.matrix.groups in config:
    "groups": {
      "!roomId:example.com": {
        "allow": true,
        "requireMention": false
      }
    }
  3. Restart the gateway
  4. Send a message in that room
  5. Check the session key assigned to the message

Expected behavior

The message should be routed to a group session (e.g. agent:main:matrix:channel:!roomId:example.com) because the room is explicitly configured in groups.

Actual behavior

The message is routed to the main DM session (agent:main:main) because directTracker.isDirectMessage() returns true for any 2-member room, regardless of the groups config.

OpenClaw version

2026.2.15

Operating system

Debian 12 / Linux

Install method

npm global

Logs, screenshots, and evidence

No error in logs as the DM classification is silent. Verified by comparing session keys: messages in 2-member configured rooms get `agent:main:main` instead of `agent:main:matrix:channel:!roomId`.

Impact and severity

Affected: Any Matrix user with project-specific rooms where only the bot and one user are members
Severity: High (blocks intended workflow)
Frequency: 100% repro
Consequence: All project rooms share the main session context instead of being isolated. Cross-project context leakage, no per-room conversation history.

Additional information

Workaround: patch src/matrix/monitor/handler.ts to check roomsConfig keys before calling directTracker.isDirectMessage():

const explicitlyConfiguredAsGroup = roomsConfig && Object.keys(roomsConfig).some(
  (key) => key === roomId || (roomAliases && roomAliases.includes(key))
);
const isDirectMessage = explicitlyConfiguredAsGroup
  ? false
  : await directTracker.isDirectMessage({ roomId, senderId, selfUserId });

The root cause is in createDirectRoomTracker in direct.ts which classifies rooms by member count. The groups config should take precedence over heuristic DM detection.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions