mirror of https://github.com/openclaw/openclaw.git
* 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> |
||
|---|---|---|
| .. | ||
| isolated-agent | ||
| service | ||
| cron-protocol-conformance.test.ts | ||
| delivery.failure-notify.test.ts | ||
| delivery.test.ts | ||
| delivery.ts | ||
| heartbeat-policy.test.ts | ||
| heartbeat-policy.ts | ||
| isolated-agent.auth-profile-propagation.test.ts | ||
| isolated-agent.delivers-response-has-heartbeat-ok-but-includes.test.ts | ||
| isolated-agent.delivery-awareness.test.ts | ||
| isolated-agent.delivery-target-thread-session.test.ts | ||
| isolated-agent.delivery.test-helpers.ts | ||
| isolated-agent.direct-delivery-core-channels.test.ts | ||
| isolated-agent.direct-delivery-forum-topics.test.ts | ||
| isolated-agent.helpers.test.ts | ||
| isolated-agent.lane.test.ts | ||
| isolated-agent.mocks.ts | ||
| isolated-agent.model-formatting.test.ts | ||
| isolated-agent.skips-delivery-without-whatsapp-recipient-besteffortdeliver-true.test.ts | ||
| isolated-agent.subagent-model.test.ts | ||
| isolated-agent.test-harness.ts | ||
| isolated-agent.test-setup.ts | ||
| isolated-agent.ts | ||
| isolated-agent.uses-last-non-empty-agent-text-as.test.ts | ||
| legacy-delivery.ts | ||
| normalize.test.ts | ||
| normalize.ts | ||
| parse.ts | ||
| payload-migration.ts | ||
| run-log.test.ts | ||
| run-log.ts | ||
| schedule.test.ts | ||
| schedule.ts | ||
| service.armtimer-tight-loop.test.ts | ||
| service.delivery-plan.test.ts | ||
| service.every-jobs-fire.test.ts | ||
| service.failure-alert.test.ts | ||
| service.get-job.test.ts | ||
| service.heartbeat-ok-summary-suppressed.test.ts | ||
| service.issue-13992-regression.test.ts | ||
| service.issue-16156-list-skips-cron.test.ts | ||
| service.issue-17852-daily-skip.test.ts | ||
| service.issue-19676-at-reschedule.test.ts | ||
| service.issue-22895-every-next-run.test.ts | ||
| service.issue-35195-backup-timing.test.ts | ||
| service.issue-regressions.test-helpers.ts | ||
| service.issue-regressions.test.ts | ||
| service.jobs.test.ts | ||
| service.jobs.top-of-hour-stagger.test.ts | ||
| service.list-page-sort-guards.test.ts | ||
| service.main-job-passes-heartbeat-target-last.test.ts | ||
| service.persists-delivered-status.test.ts | ||
| service.prevents-duplicate-timers.test.ts | ||
| service.read-ops-nonblocking.test.ts | ||
| service.rearm-timer-when-running.test.ts | ||
| service.restart-catchup.test.ts | ||
| service.runs-one-shot-main-job-disables-it.test.ts | ||
| service.session-reaper-in-finally.test.ts | ||
| service.skips-main-jobs-empty-systemevent-text.test.ts | ||
| service.store-load-invalid-main-job.test.ts | ||
| service.store-migration.test.ts | ||
| service.store.migration.test.ts | ||
| service.test-harness.ts | ||
| service.ts | ||
| session-reaper.test.ts | ||
| session-reaper.ts | ||
| stagger.test.ts | ||
| stagger.ts | ||
| store-migration.test.ts | ||
| store-migration.ts | ||
| store.test.ts | ||
| store.ts | ||
| types-shared.ts | ||
| types.ts | ||
| validate-timestamp.ts | ||
| webhook-url.ts | ||