Skip to content

fix: canonicalize session keys at write time (#29683)#30654

Merged
obviyus merged 9 commits intoopenclaw:mainfrom
thomasxm:fix/session-key-canonicalization
Mar 29, 2026
Merged

fix: canonicalize session keys at write time (#29683)#30654
obviyus merged 9 commits intoopenclaw:mainfrom
thomasxm:fix/session-key-canonicalization

Conversation

@thomasxm
Copy link
Copy Markdown
Contributor

@thomasxm thomasxm commented Mar 1, 2026

Summary

  • Root cause: resolveSessionKey() uses hardcoded DEFAULT_AGENT_ID="main" for session key construction, but all read paths canonicalize via resolveSessionStoreKey() using live config. When the configured default agent differs from "main" (or mainKey differs from "main"), writes and reads produce different keys, orphaning session transcripts on every restart.
  • Fix: Wrap all three write-path resolveSessionKey() call sites with canonicalizeMainSessionAlias() so written keys match what reads produce.
  • Migration: Add migrateOrphanedSessionKeys() to scan agent session stores on startup and rename orphaned raw keys to canonical form, merging duplicates by most-recent updatedAt.

Write paths fixed

File Function Change
src/auto-reply/reply/session.ts initSessionState Wrap line 275 with canonicalizeMainSessionAlias
src/web/auto-reply/heartbeat-runner.ts runWebHeartbeatOnce Wrap resolveSessionKey() output
src/cron/isolated-agent/session-key.ts resolveCronAgentSessionKey Accept optional cfg, apply canonicalization

Migration details

migrateOrphanedSessionKeys runs unconditionally during autoMigrateLegacyState:

  1. Scans all known agent session stores (config + on-disk discovery)
  2. Detects keys with agent:main: prefix in non-"main" agent stores (cross-agent orphans)
  3. Remaps to the correct agent prefix and applies alias canonicalization
  4. Merges duplicates (orphan + canonical) by keeping the most recently updated entry
  5. Writes back with skipMaintenance: true to avoid side effects during startup
  6. Idempotent — running twice produces no additional changes

Test plan

  • 8 unit tests for resolveCronAgentSessionKey (4 new for canonicalization)
  • 6 unit tests for migrateOrphanedSessionKeys (new file):
    • Renames orphaned raw key to canonical form
    • Keeps most recently updated entry on conflict
    • Skips already-canonical stores
    • Handles missing store files gracefully
    • Idempotent (second run = no changes)
    • No-ops when default agentId and mainKey are both "main"
  • TypeScript compilation passes
  • Lint/format clean

Closes #29683
Related: #21850, #23615, #18572, #25373, #1663

@openclaw-barnacle openclaw-barnacle bot added channel: whatsapp-web Channel integration: whatsapp-web size: M labels Mar 1, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9ca2caa60f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 1, 2026

Greptile Summary

This PR fixes a critical session key canonicalization bug that caused orphaned session transcripts on every restart when the configured default agent differed from "main" or when mainKey differed from "main".

The fix is well-architected with three complementary changes:

  • Wraps all three write paths (initSessionState, runWebHeartbeatOnce, resolveCronAgentSessionKey) with canonicalizeMainSessionAlias() to ensure written keys match what read paths produce
  • Adds migrateOrphanedSessionKeys() migration that runs unconditionally on startup to fix existing orphaned sessions
  • Migration is idempotent, handles cross-agent orphans correctly, and merges duplicates by keeping the most recently updated entry

Key changes:

  • src/auto-reply/reply/session.ts: Canonicalizes session key at write time in initSessionState
  • src/web/auto-reply/heartbeat-runner.ts: Canonicalizes session key in runWebHeartbeatOnce
  • src/cron/isolated-agent/session-key.ts: Adds canonicalization to resolveCronAgentSessionKey with optional config parameter
  • src/infra/state-migrations.ts: Adds migration logic to detect and rename orphaned session keys across all agent stores

Test coverage: 14 new tests cover canonicalization behavior, migration scenarios, idempotency, and edge cases.

Confidence Score: 5/5

  • This PR is safe to merge with high confidence
  • The implementation correctly addresses the root cause with comprehensive fixes across all write paths. The migration strategy is sound (idempotent, handles duplicates correctly, uses skipMaintenance). Test coverage is thorough with 14 new tests covering canonicalization, migration, edge cases, and idempotency. The changes are focused and well-documented with clear inline comments explaining the fix.
  • No files require special attention

Last reviewed commit: ce5b534

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7072d2a4c4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c8b6e37554

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@Kaspre
Copy link
Copy Markdown

Kaspre commented Mar 27, 2026

We're hitting this exact bug on v2026.3.24 — Discord DM sessions are silently orphaned after gateway restarts. Just commented on #29683 with a detailed reproduction.

Our case: Agent had an active DM session where a new extension was discussed and confirmed as trusted. Gateway restarted (config change → SIGUSR1), and the agent got a fresh DM session with zero context — treated the extension as suspicious prompt injection and refused to use it. The group channel session on the same agent survived the restart fine; only the direct DM session was orphaned.

We confirmed canonicalizeMainSessionAlias exists in v2026.3.24 and is called at 3 read-path sites but missing from the write paths this PR fixes. The migration piece (migrateOrphanedSessionKeys) would also help clean up the orphaned sessions we've accumulated.

This is causing real operational impact for us — we've worked around it with AGENTS.md documentation so agents can re-orient after restarts, but that's a band-aid. Would love to see this merged. Happy to help test if that's useful.

@thomasxm thomasxm force-pushed the fix/session-key-canonicalization branch from 353bf00 to 7cdf93a Compare March 28, 2026 01:12
@openclaw-barnacle openclaw-barnacle bot added gateway Gateway runtime size: L and removed size: M labels Mar 28, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b75b5551e1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@openclaw-barnacle openclaw-barnacle bot added the docs Improvements or additions to documentation label Mar 28, 2026
@thomasxm
Copy link
Copy Markdown
Contributor Author

@joshavant @jacobtomlinson @gumadeiras — requesting a review on this month-old PR.

This fixes silent session data loss: DM sessions are orphaned on gateway restart when the configured default agent differs from "main". A user (@Kaspre) independently confirmed the bug in production on v2026.3.24 — see #29683.

What changed since the original PR:

  • Rebased onto latest main (was 26 days stale)
  • Added gateway startup migration hook so accumulated orphans are cleaned up automatically on upgrade (not just via openclaw doctor)
  • Fixed cross-agent legacy alias remapping in canonicalizeMainSessionAlias — the original PR missed agent:main:*agent:<configuredAgent>:* canonicalization
  • Added write/read round-trip tests proving the fix
  • Updated plugin-sdk API baseline
  • All Codex review comments addressed and resolved

CI core checks pass. The failing channel extension tests are pre-existing on main.

Greptile gave 5/5 confidence on the original implementation. @Kaspre confirmed real operational impact and offered to help test.

@openclaw-barnacle
Copy link
Copy Markdown

Please don’t spam-ping multiple maintainers at once. Be patient, or join our community Discord for help: https://discord.gg/clawd

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df2154f3d6

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@thomasxm thomasxm force-pushed the fix/session-key-canonicalization branch from df2154f to 54b4d93 Compare March 28, 2026 11:02
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 54b4d938b9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c1045e5f4f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@openclaw-barnacle openclaw-barnacle bot added size: M and removed gateway Gateway runtime size: L labels Mar 29, 2026
@obviyus obviyus self-assigned this Mar 29, 2026
Your Name added 6 commits March 29, 2026 18:53
…ions (openclaw#29683)

resolveSessionKey() uses hardcoded DEFAULT_AGENT_ID="main", but all read
paths canonicalize via cfg. When the configured default agent differs
(e.g. "ops" with mainKey "work"), writes produce "agent:main:main" while
reads look up "agent:ops:work", orphaning transcripts on every restart.

Fix all three write-path call sites by wrapping with
canonicalizeMainSessionAlias:
- initSessionState (auto-reply/reply/session.ts)
- runWebHeartbeatOnce (web/auto-reply/heartbeat-runner.ts)
- resolveCronAgentSessionKey (cron/isolated-agent/session-key.ts)

Add startup migration (migrateOrphanedSessionKeys) to rename existing
orphaned keys to canonical form, merging by most-recent updatedAt.
…t key

P1: migrateOrphanedSessionKeys now tracks agentId alongside each store
path in a Map instead of inferring from the filesystem path. This
correctly handles custom session.store templates outside the default
agents/<id>/ layout.

P2: Pass the already-canonicalized sessionKey to getSessionSnapshot so
the heartbeat snapshot reads/restores use the same key as the write path.
migrateOrphanedSessionKeys runs before detectLegacyStateMigrations, so
it can canonicalize legacy keys (e.g. "main" → "agent:main:main") before
the legacy detector sees them. This caused the early return path to skip
logging, breaking doctor-state-migrations tests that assert log.info was
called.

Extract logMigrationResults helper and call it at every return point.
P1: When session.store has no {agentId}, all agents resolve to the same
file. Track all agentIds per store path (Map<path, Set<id>>) and run
canonicalization once per agent. Skip cross-agent "agent:main:*"
remapping when "main" is a legitimate configured agent sharing the store,
to avoid merging its data into another agent's namespace.

P2: Use expandHomePrefix (environment-aware ~ resolution) instead of
os.homedir() in resolveStorePathFromTemplate, matching the runtime
resolveStorePath behavior for OPENCLAW_HOME/HOME overrides.
Only remap agent:main:* keys where the suffix is a main session alias
("main" or the configured mainKey). Other agent:main:* keys — hooks,
subagents, cron sessions, per-sender keys — may be intentional
cross-agent references and must not be silently moved into another
agent's namespace.
@obviyus obviyus force-pushed the fix/session-key-canonicalization branch from 645f058 to d3deacb Compare March 29, 2026 13:28
@openclaw-barnacle openclaw-barnacle bot removed the docs Improvements or additions to documentation label Mar 29, 2026
Copy link
Copy Markdown
Contributor

@obviyus obviyus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed latest changes; landing now.

@obviyus obviyus merged commit 0a01386 into openclaw:main Mar 29, 2026
7 checks passed
@obviyus
Copy link
Copy Markdown
Contributor

obviyus commented Mar 29, 2026

Landed on main.

Thanks @thomasxm.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3deacba84

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +19 to +22
return canonicalizeMainSessionAlias({
cfg: params.cfg,
agentId: params.agentId,
sessionKey: raw,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve explicit main-agent session keys in cron isolation

This canonicalization rewrites explicit keys like agent:main:main / agent:main:<mainKey> to the job agent, so isolated cron runs can silently ignore a user-specified session namespace. Fresh evidence: cron normalizes sessionTarget: "current" into session:<sessionKey> verbatim (src/cron/normalize.ts:457-473) and server-cron passes that custom key directly into runCronIsolatedAgentTurn (src/gateway/server-cron.ts:286-293), so these forms are not always orphan aliases. In setups with both a main agent and a different default agent, this remap can make jobs write/read the wrong session history.

Useful? React with 👍 / 👎.

alexjiang1 pushed a commit to alexjiang1/openclaw that referenced this pull request Mar 31, 2026
…thomasxm)

* fix: canonicalize session keys at write time to prevent orphaned sessions (openclaw#29683)

resolveSessionKey() uses hardcoded DEFAULT_AGENT_ID="main", but all read
paths canonicalize via cfg. When the configured default agent differs
(e.g. "ops" with mainKey "work"), writes produce "agent:main:main" while
reads look up "agent:ops:work", orphaning transcripts on every restart.

Fix all three write-path call sites by wrapping with
canonicalizeMainSessionAlias:
- initSessionState (auto-reply/reply/session.ts)
- runWebHeartbeatOnce (web/auto-reply/heartbeat-runner.ts)
- resolveCronAgentSessionKey (cron/isolated-agent/session-key.ts)

Add startup migration (migrateOrphanedSessionKeys) to rename existing
orphaned keys to canonical form, merging by most-recent updatedAt.

* fix: address review — track agent IDs in migration map, align snapshot key

P1: migrateOrphanedSessionKeys now tracks agentId alongside each store
path in a Map instead of inferring from the filesystem path. This
correctly handles custom session.store templates outside the default
agents/<id>/ layout.

P2: Pass the already-canonicalized sessionKey to getSessionSnapshot so
the heartbeat snapshot reads/restores use the same key as the write path.

* fix: log migration results at all early return points

migrateOrphanedSessionKeys runs before detectLegacyStateMigrations, so
it can canonicalize legacy keys (e.g. "main" → "agent:main:main") before
the legacy detector sees them. This caused the early return path to skip
logging, breaking doctor-state-migrations tests that assert log.info was
called.

Extract logMigrationResults helper and call it at every return point.

* fix: handle shared stores and ~ expansion in migration

P1: When session.store has no {agentId}, all agents resolve to the same
file. Track all agentIds per store path (Map<path, Set<id>>) and run
canonicalization once per agent. Skip cross-agent "agent:main:*"
remapping when "main" is a legitimate configured agent sharing the store,
to avoid merging its data into another agent's namespace.

P2: Use expandHomePrefix (environment-aware ~ resolution) instead of
os.homedir() in resolveStorePathFromTemplate, matching the runtime
resolveStorePath behavior for OPENCLAW_HOME/HOME overrides.

* fix: narrow cross-agent remap to provable orphan aliases only

Only remap agent:main:* keys where the suffix is a main session alias
("main" or the configured mainKey). Other agent:main:* keys — hooks,
subagents, cron sessions, per-sender keys — may be intentional
cross-agent references and must not be silently moved into another
agent's namespace.

* fix: run orphan-key session migration at gateway startup (openclaw#29683)

* fix: canonicalize cross-agent legacy main aliases in session keys (openclaw#29683)

* fix: guard shared-store migration against cross-agent legacy alias remap (openclaw#29683)

* refactor: split session-key migration out of pr 30654

---------

Co-authored-by: Your Name <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
livingghost pushed a commit to livingghost/openclaw that referenced this pull request Mar 31, 2026
…thomasxm)

* fix: canonicalize session keys at write time to prevent orphaned sessions (openclaw#29683)

resolveSessionKey() uses hardcoded DEFAULT_AGENT_ID="main", but all read
paths canonicalize via cfg. When the configured default agent differs
(e.g. "ops" with mainKey "work"), writes produce "agent:main:main" while
reads look up "agent:ops:work", orphaning transcripts on every restart.

Fix all three write-path call sites by wrapping with
canonicalizeMainSessionAlias:
- initSessionState (auto-reply/reply/session.ts)
- runWebHeartbeatOnce (web/auto-reply/heartbeat-runner.ts)
- resolveCronAgentSessionKey (cron/isolated-agent/session-key.ts)

Add startup migration (migrateOrphanedSessionKeys) to rename existing
orphaned keys to canonical form, merging by most-recent updatedAt.

* fix: address review — track agent IDs in migration map, align snapshot key

P1: migrateOrphanedSessionKeys now tracks agentId alongside each store
path in a Map instead of inferring from the filesystem path. This
correctly handles custom session.store templates outside the default
agents/<id>/ layout.

P2: Pass the already-canonicalized sessionKey to getSessionSnapshot so
the heartbeat snapshot reads/restores use the same key as the write path.

* fix: log migration results at all early return points

migrateOrphanedSessionKeys runs before detectLegacyStateMigrations, so
it can canonicalize legacy keys (e.g. "main" → "agent:main:main") before
the legacy detector sees them. This caused the early return path to skip
logging, breaking doctor-state-migrations tests that assert log.info was
called.

Extract logMigrationResults helper and call it at every return point.

* fix: handle shared stores and ~ expansion in migration

P1: When session.store has no {agentId}, all agents resolve to the same
file. Track all agentIds per store path (Map<path, Set<id>>) and run
canonicalization once per agent. Skip cross-agent "agent:main:*"
remapping when "main" is a legitimate configured agent sharing the store,
to avoid merging its data into another agent's namespace.

P2: Use expandHomePrefix (environment-aware ~ resolution) instead of
os.homedir() in resolveStorePathFromTemplate, matching the runtime
resolveStorePath behavior for OPENCLAW_HOME/HOME overrides.

* fix: narrow cross-agent remap to provable orphan aliases only

Only remap agent:main:* keys where the suffix is a main session alias
("main" or the configured mainKey). Other agent:main:* keys — hooks,
subagents, cron sessions, per-sender keys — may be intentional
cross-agent references and must not be silently moved into another
agent's namespace.

* fix: run orphan-key session migration at gateway startup (openclaw#29683)

* fix: canonicalize cross-agent legacy main aliases in session keys (openclaw#29683)

* fix: guard shared-store migration against cross-agent legacy alias remap (openclaw#29683)

* refactor: split session-key migration out of pr 30654

---------

Co-authored-by: Your Name <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
pgondhi987 pushed a commit to pgondhi987/openclaw that referenced this pull request Mar 31, 2026
…thomasxm)

* fix: canonicalize session keys at write time to prevent orphaned sessions (openclaw#29683)

resolveSessionKey() uses hardcoded DEFAULT_AGENT_ID="main", but all read
paths canonicalize via cfg. When the configured default agent differs
(e.g. "ops" with mainKey "work"), writes produce "agent:main:main" while
reads look up "agent:ops:work", orphaning transcripts on every restart.

Fix all three write-path call sites by wrapping with
canonicalizeMainSessionAlias:
- initSessionState (auto-reply/reply/session.ts)
- runWebHeartbeatOnce (web/auto-reply/heartbeat-runner.ts)
- resolveCronAgentSessionKey (cron/isolated-agent/session-key.ts)

Add startup migration (migrateOrphanedSessionKeys) to rename existing
orphaned keys to canonical form, merging by most-recent updatedAt.

* fix: address review — track agent IDs in migration map, align snapshot key

P1: migrateOrphanedSessionKeys now tracks agentId alongside each store
path in a Map instead of inferring from the filesystem path. This
correctly handles custom session.store templates outside the default
agents/<id>/ layout.

P2: Pass the already-canonicalized sessionKey to getSessionSnapshot so
the heartbeat snapshot reads/restores use the same key as the write path.

* fix: log migration results at all early return points

migrateOrphanedSessionKeys runs before detectLegacyStateMigrations, so
it can canonicalize legacy keys (e.g. "main" → "agent:main:main") before
the legacy detector sees them. This caused the early return path to skip
logging, breaking doctor-state-migrations tests that assert log.info was
called.

Extract logMigrationResults helper and call it at every return point.

* fix: handle shared stores and ~ expansion in migration

P1: When session.store has no {agentId}, all agents resolve to the same
file. Track all agentIds per store path (Map<path, Set<id>>) and run
canonicalization once per agent. Skip cross-agent "agent:main:*"
remapping when "main" is a legitimate configured agent sharing the store,
to avoid merging its data into another agent's namespace.

P2: Use expandHomePrefix (environment-aware ~ resolution) instead of
os.homedir() in resolveStorePathFromTemplate, matching the runtime
resolveStorePath behavior for OPENCLAW_HOME/HOME overrides.

* fix: narrow cross-agent remap to provable orphan aliases only

Only remap agent:main:* keys where the suffix is a main session alias
("main" or the configured mainKey). Other agent:main:* keys — hooks,
subagents, cron sessions, per-sender keys — may be intentional
cross-agent references and must not be silently moved into another
agent's namespace.

* fix: run orphan-key session migration at gateway startup (openclaw#29683)

* fix: canonicalize cross-agent legacy main aliases in session keys (openclaw#29683)

* fix: guard shared-store migration against cross-agent legacy alias remap (openclaw#29683)

* refactor: split session-key migration out of pr 30654

---------

Co-authored-by: Your Name <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
jlapenna added a commit to jlapenna/openclaw that referenced this pull request Apr 3, 2026
…vent tests

Updates the assertion in the `routes /btw replies through side-result events` test block to expect the fully resolved `agent:main:main` session key. This resolves a pre-existing failing unit test on the main branch where the mock assertions were lagging behind recent production changes to the session-key identification format.

Root Cause: PR openclaw#30654 (`fix: canonicalize session keys at write time` by @thomasxm) updated the `sessionKey` format emitted by the gateway to use fully qualified keys to prevent orphans, but missed updating this specific test mock.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: whatsapp-web Channel integration: whatsapp-web size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: initSessionState uses raw session key while all read paths canonicalize — causes silent session loss on reconnect

3 participants