Agents/channels: route cross-agent subagent spawns through the target agent's bound channel account while preserving peer and workspace/role-scoped bindings, so child sessions no longer inherit the caller's account in shared rooms, workspaces, or multi-account setups.
Troubleshooting guide for fixes introduced in OpenClaw v2026.4.19-beta.1.
Troubleshooting: Cross-Agent Subagent Spawns Using Wrong Account Identity
Release: v2026.4.19-beta.1
Severity: Medium
Component: openclaw-agents, openclaw-routing
Symptoms
If you are running a multi-agent deployment on Matrix (or another channel plugin), you may observe the following:
- A child session spawned on behalf of another agent posts with the parent caller’s identity instead of the target agent’s bound account.
- In shared rooms or workspaces, speaker attribution appears wrong β messages from a subagent appear to come from the spawning agent.
- When an agent is bound to different accounts per room or peer context, subagents do not respect the per-room binding and instead use whichever account resolved first.
- In multi-account setups, a child agent intended to operate under its own bound identity ends up operating under the caller’s account.
Root Cause
When a parent session spawns a child agent for a different target agent, the routing logic was not correctly resolving the target’s bound account. Instead, deliveryContext.accountId was being seeded with the caller’s account before target bindings were consulted.
The resolveFirstBoundAccountId helper originally matched only on channel + agent, meaning agents bound to multiple rooms or peers received “first binding wins” semantics regardless of the active room or peer context. This caused nondeterministic behavior and broken speaker identity in shared-room scenarios.
Additionally, the prefix parsing for delivery targets (e.g., room:<id>, channel:<id>, conversation:<id>) was inconsistent across channel plugins, leading to failures in extracting the correct peer identifier for lookup.
Step-by-Step Fix
1. Upgrade to the Fixed Release
Upgrade to v2026.4.19-beta.1 or later. This release introduces:
resolveRequesterOriginForChild(...)insrc/agents/subagent-spawn.ts, which prefers the target agent’s bound account over the caller’s.- A four-tier precedence model in
resolveFirstBoundAccountIdwithinsrc/routing/bound-account-read.ts, supporting peer-aware matching.
2. Verify Delivery-Target Prefix Handling
Ensure your channel configuration uses normalized delivery-target prefixes. The fix strips the following prefixes generically:
// Generic prefix peeler (matches patterns like `room:`, `channel:`, `conversation:`, etc.)
const rawPeerId = agentTo.replace(/^[a-z][a-z0-9_-]*:/, '');
If your channel plugin uses custom two-part prefixes (e.g., line:group:<id>), ensure the plugin’s inferTargetChatType is implemented to disambiguate. Without it, the peeler strips the first prefix only and infers kind from the second segment.
3. Reconfigure Multi-Room Bindings (if applicable)
If an agent was previously bound to multiple rooms with a single fallback account, the new precedence model now selects per-peer. Ensure each room’s binding is explicitly configured:
// Example: agent bound to different accounts per room
agent: {
bindings: [
{ channel: "matrix", agent: "agent-id", peer: "room-id-1", accountId: "account-1" },
{ channel: "matrix", agent: "agent-id", peer: "room-id-2", accountId: "account-2" }
]
}
Verification
After upgrading, confirm the fix by running the lifecycle test suite:
pnpm test:changed src/agents/openclaw-tools.subagents.sessions-spawn.lifecycle.test.ts
All 15 lifecycle tests should pass. Specifically, verify these scenarios:
- Target agent’s bound account used β Spawning a child for another agent in a shared room uses the target’s account, not the caller’s.
- Same-agent spawn preserves caller β Spawning a child for the same agent still uses the caller’s account (no unnecessary re-resolution).
- Prefix stripping works β Targets like
room:<id>orconversation:<id>correctly resolve to the peer binding. - Kind inference for embedded markers β Matrix-style targets like
room:@user:servercorrectly classify asdirect.
For live validation, spawn a subagent in a bound Matrix room and confirm it posts from the target agent’s identity.
Common Pitfalls
Missing
inferTargetChatTypein channel plugin: If your channel plugin does not implementinferTargetChatType, the fix relies on prefix-derived kind inference. Ensure any two-part prefixes are recognized or implement the hook.Multi-room agents without explicit peer bindings: Agents bound to multiple rooms may fall back to the channel-only binding if no peer-specific binding exists. Add explicit peer bindings per room to avoid ambiguity.
Kind equivalence:
groupandchannelkinds are treated as equivalent in wildcard matching (mirroringpeerKindMatchesinresolve-route.ts). Ensure your bindings use consistent kind labels.Peerless callers (cron delivery): The helper remains backward-compatible β callers passing no
peerId/peerKindreceive the same binding as before via the peerless fallback tier.
Related Errors
If you see the following in logs, the upgrade should resolve them:
deliveryContext.accountIdmismatches between parent and child sessions in Matrix rooms- Subagent messages attributed to the wrong sender in shared-room deployments
- “First binding wins” behavior causing nondeterministic account selection across rooms
Reference: PR #67508 β Route cross-agent subagent spawns through target agent’s bound channel account
Release: v2026.4.19-beta.1