openclaw/extensions/whatsapp/src
Thomas M 0a01386756
fix: canonicalize session keys at write time (#30654) (thanks @thomasxm)
* fix: canonicalize session keys at write time to prevent orphaned sessions (#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 (#29683)

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

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

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

---------

Co-authored-by: Your Name <your_email@example.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-03-29 18:59:25 +05:30
..
auto-reply fix: canonicalize session keys at write time (#30654) (thanks @thomasxm) 2026-03-29 18:59:25 +05:30
inbound refactor: move channel dedupe helpers onto core sdk 2026-03-28 02:58:45 +00:00
accounts.test.ts refactor: share remaining account config helpers 2026-03-22 19:45:59 +00:00
accounts.ts refactor: move provider seams behind plugin sdk surfaces 2026-03-27 23:26:26 +00:00
accounts.whatsapp-auth.test.ts refactor(plugins): decouple bundled plugin runtime loading 2026-03-29 09:10:38 +01:00
action-runtime-target-auth.ts
action-runtime.test.ts
action-runtime.ts
active-listener.test.ts refactor: tighten split-runtime live-state guardrails 2026-03-24 21:58:50 -07:00
active-listener.ts refactor: tighten split-runtime live-state guardrails 2026-03-24 21:58:50 -07:00
agent-tools-login.ts
auth-store.ts refactor: move provider seams behind plugin sdk surfaces 2026-03-27 23:26:26 +00:00
auto-reply.broadcast-groups.combined.test.ts
auto-reply.broadcast-groups.test-harness.ts
auto-reply.impl.ts
auto-reply.test-harness.ts refactor: move test harnesses off infra runtime 2026-03-28 06:52:06 +00:00
auto-reply.ts
auto-reply.web-auto-reply.compresses-common-formats-jpeg-cap.test.ts test: speed up whatsapp and signal suites 2026-03-24 16:26:58 +00:00
auto-reply.web-auto-reply.connection-and-logging.e2e.test.ts refactor(plugins): decouple bundled plugin runtime loading 2026-03-29 09:10:38 +01:00
auto-reply.web-auto-reply.last-route.test.ts test: harden channel suite isolation 2026-03-23 11:09:12 +00:00
channel.runtime.ts
channel.setup.ts
channel.test.ts refactor(plugins): decouple bundled plugin runtime loading 2026-03-29 09:10:38 +01:00
channel.ts fix(regression): restore whatsapp cold-runtime chunking 2026-03-27 21:23:18 -05:00
config-schema.ts refactor: move channel config metadata into plugin-owned manifests 2026-03-27 01:59:30 +00:00
config-ui-hints.ts refactor: move channel config metadata into plugin-owned manifests 2026-03-27 01:59:30 +00:00
creds-files.ts refactor: move provider seams behind plugin sdk surfaces 2026-03-27 23:26:26 +00:00
directory-config.ts refactor: share scoped account accessor adapters 2026-03-22 20:30:21 +00:00
group-policy.contract.test.ts refactor: move extension-owned tests to extensions 2026-03-27 21:37:09 +00:00
group-policy.ts
identity.ts refactor: unify whatsapp identity handling 2026-03-25 04:46:24 -07:00
inbound.contract.test.ts refactor: move extension-owned tests to extensions 2026-03-27 21:37:09 +00:00
inbound.media.test.ts fix(ci): stabilize whatsapp extension checks 2026-03-23 15:50:19 -07:00
inbound.test.ts test: speed up telegram and whatsapp suites 2026-03-24 21:48:07 +00:00
inbound.ts
login-qr.test.ts fix(ci): stabilize whatsapp extension checks 2026-03-23 15:50:19 -07:00
login-qr.ts fix(ci): stabilize whatsapp extension checks 2026-03-23 15:50:19 -07:00
login.coverage.test.ts test(whatsapp): preserve session exports in login coverage 2026-03-23 15:50:19 -07:00
login.test.ts refactor: dedupe test and runtime seams 2026-03-24 23:33:30 +00:00
login.ts fix(ci): stabilize whatsapp extension checks 2026-03-23 15:50:19 -07:00
logout.test.ts
media.test.ts refactor(plugins): decouple bundled plugin runtime loading 2026-03-29 09:10:38 +01:00
media.ts refactor: share web media loader 2026-03-26 14:55:32 +00:00
monitor-inbox.allows-messages-from-senders-allowfrom-list.test.ts fix(whatsapp): drop fromMe echoes in self-chat DMs using outbound ID tracking (#54570) 2026-03-26 02:24:24 -03:00
monitor-inbox.append-upsert.test.ts refactor(test): dedupe shared test helpers 2026-03-21 23:07:51 +00:00
monitor-inbox.blocks-messages-from-unauthorized-senders-not-allowfrom.test.ts test: speed up whatsapp and signal suites 2026-03-24 16:26:58 +00:00
monitor-inbox.captures-media-path-image-messages.test.ts test: speed up whatsapp and signal suites 2026-03-24 16:26:58 +00:00
monitor-inbox.streams-inbound-messages.test.ts refactor: unify whatsapp identity handling 2026-03-25 04:46:24 -07:00
monitor-inbox.test-harness.ts refactor: align pairing replies, daemon hints, and feishu mention policy 2026-03-25 04:22:53 -07:00
normalize-target.ts refactor(plugins): move remaining channel and provider ownership out of src 2026-03-22 19:13:25 -07:00
normalize.ts refactor(plugins): move remaining channel and provider ownership out of src 2026-03-22 19:13:25 -07:00
outbound-adapter.poll.test.ts test: harden channel suite isolation 2026-03-23 12:57:43 +00:00
outbound-adapter.sendpayload.test.ts
outbound-adapter.ts perf: reduce plugin runtime startup overhead 2026-03-22 09:35:36 +00:00
outbound-payload.contract.test.ts refactor: move extension-owned tests to extensions 2026-03-27 21:37:09 +00:00
pairing-security.test-harness.ts refactor: dedupe test and runtime seams 2026-03-24 23:33:30 +00:00
plugins-core.contract.test.ts refactor: move extension-owned tests to extensions 2026-03-27 21:37:09 +00:00
qr-image.ts refactor: dedupe test and runtime seams 2026-03-24 23:33:30 +00:00
reconnect.test.ts
reconnect.ts refactor: move channel backoff helpers onto runtime-env 2026-03-28 02:48:35 +00:00
resolve-outbound-target.test.ts fix(whatsapp): clarify allowFrom policy error (#54850) 2026-03-26 00:44:10 -03:00
resolve-outbound-target.ts fix(whatsapp): clarify allowFrom policy error (#54850) 2026-03-26 00:44:10 -03:00
resolve-target.test.ts test: collapse telegram and whatsapp target suites 2026-03-25 05:21:16 +00:00
runtime-api.ts refactor: continue plugin seam cleanup 2026-03-27 13:46:16 +00:00
runtime.ts
send.test.ts test: speed up whatsapp and shared test suites 2026-03-24 15:16:18 +00:00
send.ts refactor: move secure random helpers onto core sdk 2026-03-28 03:06:06 +00:00
session-errors.ts
session-route.ts
session.test.ts refactor: unify whatsapp identity handling 2026-03-25 04:46:24 -07:00
session.ts fix(ci): stabilize whatsapp extension checks 2026-03-23 15:50:19 -07:00
setup-core.ts
setup-surface.ts
shared.ts refactor: move channel config metadata into plugin-owned manifests 2026-03-27 01:59:30 +00:00
status-issues.test.ts test(whatsapp): cover monitor lifecycle states 2026-03-22 22:07:41 +00:00
status-issues.ts refactor(whatsapp): centralize web monitor state 2026-03-22 22:07:41 +00:00
test-helpers.ts fix(ci): stabilize whatsapp extension checks 2026-03-23 15:50:19 -07:00
vcard.ts