hcengineering/platform · info

reconnect workspace in upgrade switch

Error message

reconnect workspace in upgrade switch

What it means

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.

Source

Thrown at foundations/server/packages/server/src/sessionManager.ts:660

      ctx.warn('open workspace', {
        account: token.account,
        workspace: workspaceUuid,
        ...token.extra
      })

      workspace = this.createWorkspace(ctx.parent ?? ctx, ctx, token, workspaceInfo.url, workspaceInfo.dataId, branding)
      await this.workspaceProducer.send(ctx, workspaceUuid, [workspaceEvents.open()])
    }

    if (token.extra?.model === 'upgrade') {
      if (workspace.maintenance) {
        ctx.warn('reconnect workspace in upgrade', {
          account: token.account,
          workspace: workspaceUuid,
          wsUrl: workspaceInfo.url
        })
      } else {
        ctx.warn('reconnect workspace in upgrade switch', {
          email: token.account,
          workspace: workspaceUuid,
          wsUrl: workspaceInfo.url
        })

        // We need to wait in case previous upgrade connection is already closing.
        await this.switchToUpgradeSession(token, ctx.parent ?? ctx, workspace, ws)
      }
    } else {
      if (workspace.maintenance || this.maintenanceWorkspaces.has(workspace.wsId.uuid)) {
        ctx.warn('connect during upgrade', {
          account: token.account,
          workspace: workspace.wsId.url,
          sessionUsers: Array.from(workspace.sessions.values()).map((it) => it.session.getUser()),
          sessionData: Array.from(workspace.sessions.values()).map((it) => it.socket.data())
        })

        return { resp: { upgrade: true } }

View on GitHub (pinned to 63e28dc964)

Solutions

  1. No action needed if the upgrade completes — this is the expected switch log.
  2. If the switch hangs, check switchToUpgradeSession for errors and whether a prior upgrade socket is stuck open (see the preceding wait comment).
  3. Ensure only one upgrade connection per workspace; duplicate upgrade connections will serialize on this path.
Defensive patterns

Strategy: try-catch

Validate before calling

const ws = sessionManager.workspaces.get(wsUuid)
if (ws !== undefined && !ws.maintenance && token.extra?.model === 'upgrade') {
  // switch path will run; make sure no other upgrade connection is active
  assertSingleUpgradeConnection(wsUuid)
}

Type guard

function needsUpgradeSwitch(ws: Workspace | undefined): boolean {
  return ws !== undefined && !ws.maintenance
}

Try / catch

try {
  await sessionManager.getWorkspace(ctx, wsUuid, info, upgradeToken, socket)
} catch (err) {
  logger.error('upgrade session switch failed', { wsUuid, err })
  await rollbackUpgrade(wsUuid)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/8d3a1f2ccd921373. Report an issue: GitHub.