{"record":{"id":"8d3a1f2ccd921373","repo":"hcengineering/platform","slug":"reconnect-workspace-in-upgrade-switch","errorCode":null,"errorMessage":"reconnect workspace in upgrade switch","messagePattern":"reconnect workspace in upgrade switch","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"foundations/server/packages/server/src/sessionManager.ts","lineNumber":660,"sourceCode":"      ctx.warn('open workspace', {\n        account: token.account,\n        workspace: workspaceUuid,\n        ...token.extra\n      })\n\n      workspace = this.createWorkspace(ctx.parent ?? ctx, ctx, token, workspaceInfo.url, workspaceInfo.dataId, branding)\n      await this.workspaceProducer.send(ctx, workspaceUuid, [workspaceEvents.open()])\n    }\n\n    if (token.extra?.model === 'upgrade') {\n      if (workspace.maintenance) {\n        ctx.warn('reconnect workspace in upgrade', {\n          account: token.account,\n          workspace: workspaceUuid,\n          wsUrl: workspaceInfo.url\n        })\n      } else {\n        ctx.warn('reconnect workspace in upgrade switch', {\n          email: token.account,\n          workspace: workspaceUuid,\n          wsUrl: workspaceInfo.url\n        })\n\n        // We need to wait in case previous upgrade connection is already closing.\n        await this.switchToUpgradeSession(token, ctx.parent ?? ctx, workspace, ws)\n      }\n    } else {\n      if (workspace.maintenance || this.maintenanceWorkspaces.has(workspace.wsId.uuid)) {\n        ctx.warn('connect during upgrade', {\n          account: token.account,\n          workspace: workspace.wsId.url,\n          sessionUsers: Array.from(workspace.sessions.values()).map((it) => it.session.getUser()),\n          sessionData: Array.from(workspace.sessions.values()).map((it) => it.socket.data())\n        })\n\n        return { resp: { upgrade: true } }","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/server/packages/server/src/sessionManager.ts#L642-L678","documentation":"Warning logged by getWorkspace when an upgrade-model connection arrives for a workspace that is NOT in maintenance, meaning this is the first/switching upgrade connection: the manager logs it and awaits switchToUpgradeSession, which performs the session switch while pausing briefly in case a previous upgrade connection is still closing. It marks the start of the live switch to the upgraded model.","triggerScenarios":"getWorkspace with token.extra?.model === 'upgrade' and workspace.maintenance === false — the upgrade process attaches and switchToUpgradeSession(token, ctx, workspace, ws) is awaited to swap the running workspace onto the upgraded connection.","commonSituations":"Normal part of a model upgrade rollout (upgrade service connecting to perform the switch); manual re-run of an upgrade after failure; deploying a new server version that triggers workspace upgrades.","solutions":["No action needed if the upgrade completes — this is the expected switch log.","If the switch hangs, check switchToUpgradeSession for errors and whether a prior upgrade socket is stuck open (see the preceding wait comment).","Ensure only one upgrade connection per workspace; duplicate upgrade connections will serialize on this path."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const ws = sessionManager.workspaces.get(wsUuid)\nif (ws !== undefined && !ws.maintenance && token.extra?.model === 'upgrade') {\n  // switch path will run; make sure no other upgrade connection is active\n  assertSingleUpgradeConnection(wsUuid)\n}","typeGuard":"function needsUpgradeSwitch(ws: Workspace | undefined): boolean {\n  return ws !== undefined && !ws.maintenance\n}","tryCatchPattern":"try {\n  await sessionManager.getWorkspace(ctx, wsUuid, info, upgradeToken, socket)\n} catch (err) {\n  logger.error('upgrade session switch failed', { wsUuid, err })\n  await rollbackUpgrade(wsUuid)\n}","preventionTips":["Run upgrades serially per workspace to avoid competing switch connections.","Wrap switchToUpgradeSession failures with rollback logic that restores the previous model state.","Log and track upgrade durations to detect stuck switches.","Verify previous upgrade sockets are fully closed before starting a new switch."],"tags":["upgrade","session-switch","workspace","logging"],"backgroundTag":"upgrade-session-switch","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}