You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: MsgContext.canonicalKey() is not injective — distinct conversations can collapse to one gateway session key #3534
io.agentscope.harness.agent.gateway.MsgContext#canonicalKey() joins the routing components with a bare | separator and does not escape that separator inside the components, so the key is not injective: two different routing contexts can produce the same canonical key.
newMsgContext("chatui", "team|r:room-1", null, null, null, Map.of()).canonicalKey();
// "chatui|g:team|r:room-1"newMsgContext("chatui", "team", "room-1", null, null, Map.of()).canonicalKey();
// "chatui|g:team|r:room-1" <-- same key, different conversation
extra keys and values are joined the same way, so a value may also forge structural fragments.
Impact
canonicalKey() is the gateway session key (session id derivation, per-key turn gate, session -> key wake-up map). A collision routes two distinct conversations to the same gateway session, so participants of one group/room can see the other's conversation state.
Reproduction
MsgContextgroupOnly = newMsgContext("chatui", "team|r:room-1", null, null, null, Map.of());
MsgContextgroupRoom = newMsgContext("chatui", "team", "room-1", null, null, Map.of());
assertNotEquals(groupOnly.canonicalKey(), groupRoom.canonicalKey());
// fails on main: expected: not equal but was: <chatui|g:team|r:room-1>
Proposed fix
Escape % (first) and | in every component before appending. Keys without reserved characters are unchanged, so existing session mappings are preserved.
Activity