From 0c305596a27d37dbdbe4f6ecda6fc357e86466bf Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 27 Apr 2026 21:00:43 +0100 Subject: [PATCH] fix(channels): skip route updates without session creation --- CHANGELOG.md | 1 + src/channels/session.test.ts | 22 ++++++++++++++++++++++ src/channels/session.ts | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa9198687f9..cfc0e5dcb11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Channels/sessions: skip last-route writes when inbound session recording explicitly disables creation, so plugin-owned guarded inbound paths cannot create route-only phantom sessions. Carries forward #73009. Thanks @jzakirov. - Channels/Telegram: skip the optional webhook-info API call during polling-mode status checks and startup bot-label probes so long-polling setups avoid an unnecessary Telegram round trip. Carries forward #72990. Thanks @danielgruneberg. - CLI/message: load only the selected channel plugin for targeted `openclaw message` actions, and fall back to configured channel plugins when the channel must be inferred, so scripted sends avoid full bundled plugin registry scans. Fixes #73006. Thanks @jasonftl. - CLI/models: keep route-first `models status --json` stdout reserved for the JSON payload by routing auth-profile and startup diagnostics to stderr. Fixes #72962. Thanks @vishutdhar. diff --git a/src/channels/session.test.ts b/src/channels/session.test.ts index 2627a0acfe4..c75a44c7e59 100644 --- a/src/channels/session.test.ts +++ b/src/channels/session.test.ts @@ -132,4 +132,26 @@ describe("recordInboundSession", () => { senderRecipient: "9999", }); }); + + it("skips last-route updates when session creation is disabled", async () => { + await recordInboundSession({ + storePath: "/tmp/openclaw-session-store.json", + sessionKey: "agent:main:demo-channel:1234:thread:42", + ctx, + createIfMissing: false, + updateLastRoute: { + sessionKey: "agent:main:main", + channel: "demo-channel", + to: "demo-channel:1234", + }, + onRecordError: vi.fn(), + }); + + expect(recordSessionMetaFromInboundMock).toHaveBeenCalledWith( + expect.objectContaining({ + createIfMissing: false, + }), + ); + expect(updateLastRouteMock).not.toHaveBeenCalled(); + }); }); diff --git a/src/channels/session.ts b/src/channels/session.ts index 15c1e959385..54ebe996ab6 100644 --- a/src/channels/session.ts +++ b/src/channels/session.ts @@ -51,7 +51,7 @@ export async function recordInboundSession(params: { .catch(params.onRecordError); const update = params.updateLastRoute; - if (!update) { + if (!update || createIfMissing === false) { return; } if (shouldSkipPinnedMainDmRouteUpdate(update.mainDmOwnerPin)) {