Skip to content

Bug: resolveAgentRoute does not normalize input peer.kind, causing binding mismatch for "dm" vs "direct" #22730

@youngshunf

Description

@youngshunf

Bug Description

In resolveAgentRoute (resolve-route module), the binding's peer.kind is normalized via normalizeChatType() (which maps both "dm" and "direct" to "direct"), but the input peer.kind from the channel plugin is used as-is without normalization.

In matchesBindingScope, the comparison:

scope.peer.kind !== match.peer.kind

then fails when a plugin passes kind: "dm" and the binding config uses kind: "direct" (or vice versa), because "dm" !== "direct".

Location

resolveAgentRoute() in the resolve-route module, around:

const peer = input.peer ? {
    kind: input.peer.kind,          // ← NOT normalized via normalizeChatType
    id: normalizeId(input.peer.id)
} : null;

While the binding side correctly normalizes:

function normalizePeerConstraint(peer) {
    // ...
    const kind = normalizeChatType(peer.kind);  // ← normalized
    const id = normalizeId(peer.id);
    // ...
}

And normalizeChatType correctly handles both:

function normalizeChatType(raw) {
    const value = raw?.trim().toLowerCase();
    if (!value) return;
    if (value === "direct" || value === "dm") return "direct";
    if (value === "group") return "group";
    if (value === "channel") return "channel";
}

Suggested Fix

const peer = input.peer ? {
    kind: normalizeChatType(input.peer.kind),  // ← normalize here too
    id: normalizeId(input.peer.id)
} : null;

Impact

Any channel plugin that uses "dm" as peerKind (e.g. @openclaw-china/qqbot) will fail peer-based binding matching, causing messages to fall through to the default agent instead of the intended per-user agent.

Steps to Reproduce

  1. Configure multi-agent with per-user QQ bindings using peer.kind: "direct"
  2. QQ plugin (@openclaw-china/qqbot) sends peerKind: "dm" for DM messages
  3. Binding match fails silently, message routes to default (main) agent

Workaround

Patch the QQ plugin to use peerKind: "direct" instead of "dm" in resolveChatTarget().

Environment

  • OpenClaw version: 2026.2.17
  • QQ plugin: @openclaw-china/qqbot v0.1.5
  • OS: Linux (Ubuntu)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions