Skip to content

[Bug]: external raw session keys can split after sessions_send / nested agent canonicalization #63005

Description

@songshikang0111

Summary

Stable external session keys that do not start with agent-prefixed namespaces like agent: can split one logical conversation into multiple OpenClaw session records after internal sessions_send / nested agent activity.

Steps to reproduce

  1. Configure an external integration that delivers inbound messages into OpenClaw using a stable raw session key that does not start with agent:.
    Example shape:
    conversation:pair:user_a::user_b:space:space_123
  2. Let inbound traffic create and continue a normal session under that raw key.
  3. During that conversation, trigger internal sessions_send behavior that causes nested agent activity to touch the same logical conversation.
  4. Send another normal inbound message for the same raw external session key.
  5. Inspect sessions.json, transcript files, and session continuity.

Expected behavior

A raw external session key with an existing active session entry should continue to resolve to the same logical OpenClaw session.

Internal sessions_send / nested agent activity should not cause the next inbound message on that same external key to start a fresh sessionId unless a real reset or freshness rollover happened.

Actual behavior

One logical conversation can be split into multiple session records and transcript files without a true reset boundary.

Observed shape:

  • transcript A continues normally under a session created from raw external inbound
  • internal nested agent / sessions_send activity touches the same conversation
  • later inbound on the same raw key starts transcript B with a new sessionId
  • transcript A is not archived as reset history
  • sessions.json now reflects a new raw-key entry, while the internal canonicalized key may already exist separately

OpenClaw version

2026.4.2

Operating system

Ubuntu server

Install method

Self-hosted gateway from global npm install

Logs, screenshots, and evidence

Sanitized example:

Raw external key:
conversation:pair:user_a::user_b:space:space_123

The same logical conversation was split into two transcript files:

  • aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb.jsonl
  • cccccccc-4444-5555-6666-dddddddddddd.jsonl

The split happened within about one minute during continuous conversation, so it did not match:

  • daily reset timing
  • idle freshness rollover

The old transcript remained as a normal .jsonl file rather than a reset archive, suggesting this was not a normal reset path.

Code-path inspection suggests the inconsistency is:

  • some inbound/session-init paths still look up the raw external key directly
  • gateway agent paths canonicalize non-agent-prefixed keys into agent:<default-agent>:...
  • gateway writeback prunes non-canonical candidate keys as legacy aliases
  • the raw external key entry can disappear from the store even though future inbound traffic still looks it up by the raw key
  • the next inbound message then creates a fresh sessionId

Impact and severity

Affected:
External integrations that rely on stable structured session or conversation keys

Severity:
High

Frequency:
Intermittent, but reproducible when internal sessions_send / nested agent activity touches the same logical conversation

Consequence:
One logical conversation can be split across multiple sessionIds and transcript files, breaking history continuity and making session behavior difficult to reason about

Additional information

Affected component: gateway session canonicalization, session store alias pruning, inbound session initialization, and sessions_send / nested agent flows.

This appears related to, but broader than, #49202.

The issue seems to be a consistency problem between raw external session keys and canonicalized agent-scoped session keys. A likely fix would be to make raw-key handling consistent across inbound/session-init and gateway canonicalization paths, or to avoid pruning raw external keys that future inbound traffic still depends on.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions