From 035a8a6c9d464d52b932aaa4d7fd6d6edf6a7721 Mon Sep 17 00:00:00 2001 From: stefanbaxter Date: Thu, 23 Apr 2026 08:18:20 +0000 Subject: [PATCH] fix(actions): prevent unhandledRejection crash on WorkOS refresh failure The singleflight `.finally()` chain created a dangling promise with no error handler. When `authenticateWithRefreshToken` rejected (e.g. expired session), the finally chain re-rejected independently of the awaited consumer, tripping unhandledRejection and crashing the process. Attach `.catch(() => {})` to the cleanup chain. The awaited consumer still owns the real error handling. Co-Authored-By: Claude Opus 4.7 (1M context) --- services/actions/src/auth/token.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/actions/src/auth/token.js b/services/actions/src/auth/token.js index 1e958375..58fe28f5 100644 --- a/services/actions/src/auth/token.js +++ b/services/actions/src/auth/token.js @@ -75,7 +75,12 @@ export default async function tokenHandler(req, res) { return { accessToken: freshJwt, workosAccessToken: refreshResult.accessToken }; })(); inflightRefreshes.set(sessionId, refreshPromise); - refreshPromise.finally(() => inflightRefreshes.delete(sessionId)); + // Swallow the rejection on this branch — `await refreshPromise` below owns the error. + // Without the catch, `.finally()` returns an unhandled rejected promise when refresh fails, + // which crashes the process via unhandledRejection. + refreshPromise + .finally(() => inflightRefreshes.delete(sessionId)) + .catch(() => {}); } try {