{"record":{"id":"e24358b59138fdff","repo":"RocketChat/Rocket.Chat","slug":"stubmeteorstream-reset-on-sdk-reconnect-failed","errorCode":null,"errorMessage":"[stubMeteorStream] reset on SDK reconnect failed","messagePattern":"\\[stubMeteorStream\\] reset on SDK reconnect failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"apps/meteor/client/meteor/overrides/stubMeteorStream.ts","lineNumber":222,"sourceCode":"\t// callbacks → the _reconnectStopper that retries login with the latest\n\t// stored token and calls makeClientLoggedOut on failure (so the\n\t// account-manage-devices / admin-device-management / e2ee-key-reset\n\t// force-logout tests recover). The first connect is handled by the\n\t// queueMicrotask above; skip it here. The \"method result but no methods\n\t// outstanding\" / \"No callback invoker\" warnings the resent blocks\n\t// occasionally generate are caught by the bridge's async catch in\n\t// ddpSdkCollectionBridge.\n\tconst sdk = getDdpSdk();\n\tlet firstConnectHandled = false;\n\tsdk.connection.on('connected', () => {\n\t\tif (!firstConnectHandled) {\n\t\t\tfirstConnectHandled = true;\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tfire('reset');\n\t\t} catch (err) {\n\t\t\tconsole.warn('[stubMeteorStream] reset on SDK reconnect failed', err);\n\t\t}\n\t});\n\n\t// Belt-and-suspenders: when the underlying SDK socket disconnects, also reset\n\t// `Accounts._lastLoginTokenWhenPolled` so the next `_pollStoredLoginToken`\n\t// (whether triggered by the 3s polling timer or an external poke like a test's\n\t// `loginByUserState`) is forced to compare against `null` and fire a fresh\n\t// login if the stored token still exists. This covers the gap where neither\n\t// `useForceLogout` (stream message lost in the broker race) nor\n\t// `_reconnectStopper`'s `makeClientLoggedOut` ran — without this, a stored\n\t// token equal to the cached `_lastLoginTokenWhenPolled` short-circuits the\n\t// poller and the user sits with stale credentials until the next genuine\n\t// token rotation.\n\t// Belt-and-suspenders for the EE force-logout path. The existing recovery\n\t// mechanisms (useForceLogout via stream message; _reconnectStopper via\n\t// fire('reset') calling makeClientLoggedOut on auth failure) BOTH clear\n\t// _lastLoginTokenWhenPolled when they run, but in microservices the\n\t// notify-user/<uid>/force_logout stream traverses","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/client/meteor/overrides/stubMeteorStream.ts#L204-L240","documentation":"In the SDK-bridged client, a stub replaces Meteor's own DDP socket. On every SDK 'connected' event after the first, the stub fires a synthetic transport 'reset' so Meteor's connection machinery re-sends outstanding methods and retries login (via _streamHandlers.onReset and the DDP reconnect hooks). fire('reset') calls into Meteor internals and any handlers they invoke; if one of those throws, the exception is caught here and logged as '[stubMeteorStream] reset on SDK reconnect failed'. The reconnect itself already succeeded - the warning means the post-reconnect recovery pass did not fully run.","triggerScenarios":"Server closes the websocket (e.g. force-logout under microservices/ddp-streamer) and, on reconnect, a Meteor-side reset/reconnect handler throws; pending method callbacks referencing missing invokers during the resend; tests that replace Accounts internals so a reset handler meets unexpected state.","commonSituations":"Flaky networks during development where reconnect-resend hits half-finished client state; microservices deployments terminating sockets server-side; e2e tests stubbing parts of accounts-base.","solutions":["Inspect the err logged after the message - it identifies the throwing handler","Force a clean re-alignment of Meteor and SDK session state: log out and log in again (fresh loginWithToken pass)","Reload the page as the blunt recovery if the UI looks wedged (e.g. stuck on PageLoading or stale credentials after force-logout)","Maintainers: harden individual reset handlers so one bad handler cannot fail the whole reset pass"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["In app code, never register connection 'reset'/'reconnect' handlers that can throw - wrap their bodies","After force-logout or reconnect storms, detect wedged state (page on PageLoading, stale userId) and trigger re-login or a reload","In tests, avoid partially stubbing accounts-base internals that reset handlers depend on","Keep the DDP SDK and the client bridge versions in lockstep"],"tags":["console-warn","ddp","reconnect","meteor-accounts","client","stream-reset"],"backgroundTag":"ddp-reconnect-handler-error","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}