diff --git a/CHANGELOG.md b/CHANGELOG.md index 511887b8f..56c257710 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ Docs: https://docs.openclaw.ai ### Fixes - Sessions/idle reset correctness: preserve existing `updatedAt` during inbound metadata-only writes so idle-reset boundaries are not unintentionally refreshed before actual user turns. (#32379) Thanks @romeodiaz. +- Slack/socket auth failure handling: fail fast on non-recoverable auth errors (`account_inactive`, `invalid_auth`, etc.) during startup and reconnect instead of retry-looping indefinitely, including `unable_to_socket_mode_start` error payload propagation. (#32377) Thanks @scoootscooob. - Gateway/message tool reliability: avoid false `Unknown channel` failures when `message.*` actions receive platform-specific channel ids by falling back to `toolContext.currentChannelProvider`, and prevent health-monitor restart thrash for channels that just (re)started by adding a per-channel startup-connect grace window. (from #32367) Thanks @MunemHashmi. - Discord/lifecycle startup status: push an immediate `connected` status snapshot when the gateway is already connected before lifecycle debug listeners attach, with abort-guarding to avoid contradictory status flips during pre-aborted startup. (#32336) Thanks @mitchmcalister. - Cron/isolated delivery target fallback: remove early unresolved-target return so cron delivery can flow through shared outbound target resolution (including per-channel `resolveDefaultTo` fallback) when `delivery.to` is omitted. (#32364) Thanks @hclsys. diff --git a/src/slack/monitor/provider.reconnect.test.ts b/src/slack/monitor/provider.reconnect.test.ts index f2e36ad1f..b3638a209 100644 --- a/src/slack/monitor/provider.reconnect.test.ts +++ b/src/slack/monitor/provider.reconnect.test.ts @@ -42,4 +42,18 @@ describe("slack socket reconnect helpers", () => { await expect(waiter).resolves.toEqual({ event: "error", error: err }); }); + + it("preserves error payload from unable_to_socket_mode_start event", async () => { + const client = new FakeEmitter(); + const app = { receiver: { client } }; + const err = new Error("invalid_auth"); + + const waiter = __testing.waitForSlackSocketDisconnect(app as never); + client.emit("unable_to_socket_mode_start", err); + + await expect(waiter).resolves.toEqual({ + event: "unable_to_socket_mode_start", + error: err, + }); + }); }); diff --git a/src/slack/monitor/provider.ts b/src/slack/monitor/provider.ts index 1a0a9f49f..60e772c9d 100644 --- a/src/slack/monitor/provider.ts +++ b/src/slack/monitor/provider.ts @@ -105,7 +105,8 @@ function waitForSlackSocketDisconnect( } const disconnectListener = () => resolveOnce({ event: "disconnect" }); - const startFailListener = () => resolveOnce({ event: "unable_to_socket_mode_start" }); + const startFailListener = (error?: unknown) => + resolveOnce({ event: "unable_to_socket_mode_start", error }); const errorListener = (error: unknown) => resolveOnce({ event: "error", error }); const abortListener = () => resolveOnce({ event: "disconnect" });