← All Articles

OpenClaw Session Key Canonicalization — Fixing Orphaned Transcripts

OpenClaw Bug Fix Multi-Agent March 29, 2026 · Thomas M (thomasxm) · View PR #30654 →

Author Context

Thomas M (@thomasxm) is a community contributor who identified and fixed a subtle but impactful bug affecting users with custom agent configurations. The fix includes not just the code change but also a migration path for existing affected installations.

Why This Matters

OpenClaw uses session keys to identify and persist conversation transcripts. The key format is agent:{agentId}:{sessionAlias}. A bug in the session key resolution logic meant that when users configured a non-default agent ID, transcripts could be written to one key but read from another — effectively orphaning conversation history on every restart.

Who was affected: Users running multi-agent configurations where the default agent is not "main" — for example, if you configured defaultAgent: "ops" with mainKey: "work", your transcripts were being lost.

The Bug

The root cause was a mismatch between write and read paths:

// resolveSessionKey() hardcoded DEFAULT_AGENT_ID = "main"
// Write path: "agent:main:main"
// Read path (via config): "agent:ops:work"

// Result: Write and read never find each other

Three write-path call sites were affected:

All three used the hardcoded default instead of resolving through the configuration system.

The Fix

The fix wraps all three call sites with canonicalizeMainSessionAlias(), which properly resolves the session key through the configuration:

// Now consistent across read and write paths
const sessionKey = canonicalizeMainSessionAlias(rawKey, cfg);
// → "agent:ops:work" everywhere

But fixing the code isn't enough — existing users already have orphaned transcripts sitting in the wrong location.

The Migration

The PR includes a startup migration (migrateOrphanedSessionKeys) that automatically recovers orphaned transcripts:

  1. Scan the session store for keys matching agent:main:*
  2. For each key, check if it should belong to a different agent based on configuration
  3. Rename the key to its canonical form, merging by most-recent updatedAt if a conflict exists
  4. Log migration results for auditability

Edge cases handled: The migration correctly handles shared stores (where multiple agents use the same file), custom session.store templates, and avoids remapping legitimate cross-agent references like hooks, subagents, and per-sender keys.

Technical Details

The PR evolved through several iterations addressing review feedback:

The careful iteration on edge cases shows the complexity hidden in session key management when supporting flexible multi-agent configurations.

Implications

For single-agent users: No impact. The default configuration continues to work exactly as before.

For multi-agent users: If you've been seeing blank conversation history after restarts, upgrade to 2026.3.29 and your transcripts should automatically recover on first startup.

For developers: The fix establishes a clear pattern — always use canonicalizeMainSessionAlias() when constructing session keys. The hardcoded DEFAULT_AGENT_ID constant should only be used as a fallback when no configuration is available.

Next Steps

The migration runs automatically on startup. Check your logs for migrateOrphanedSessionKeys entries to confirm recovery. If you had orphaned transcripts, they should now appear in your conversation history.