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
    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