{"record":{"id":"d0313df179948e49","repo":"hcengineering/platform","slug":"reconnect-workspace-in-upgrade","errorCode":null,"errorMessage":"reconnect workspace in upgrade","messagePattern":"reconnect workspace in upgrade","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"foundations/server/packages/server/src/sessionManager.ts","lineNumber":654,"sourceCode":"    const branding =\n      (workspaceInfo.branding !== undefined\n        ? Object.values(this.brandingMap).find((b) => b.key === workspaceInfo?.branding)\n        : null) ?? null\n\n    if (workspace === undefined) {\n      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,","sourceCodeStart":636,"sourceCodeEnd":672,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/server/packages/server/src/sessionManager.ts#L636-L672","documentation":"Warning logged by getWorkspace when a connection with token.extra?.model === 'upgrade' reconnects to a workspace that is already flagged maintenance (workspace.maintenance === true). It means an upgrade client reconnected while the workspace is mid-upgrade; the connection is allowed but no session switch is performed, unlike the non-maintenance case.","triggerScenarios":"getWorkspace with token.extra.model === 'upgrade' and the resolved workspace object already has maintenance=true — e.g., an upgrade client dropped mid-upgrade and reconnected, or forceMaintenance/forceClose set the maintenance flag and the upgrade connection re-attaches.","commonSituations":"Network drop during a model upgrade causing the upgrade client to reconnect; duplicate upgrade connections racing; a previous upgrade attempt ended abnormally leaving maintenance set.","solutions":["Wait for the ongoing upgrade to finish; the reconnected upgrade client should resume/observe upgrade progress.","Verify the upgrade process (switchToUpgradeSession / upgrade pipeline) is still running and healthy; restart it if it died mid-upgrade leaving maintenance stuck.","If maintenance is stuck, use forceClose to fully tear the workspace down and let a fresh upgrade run."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"const ws = sessionManager.workspaces.get(wsUuid)\nif (ws?.maintenance === true) {\n  await waitForUpgradeCompletion(wsUuid) // poll upgrade progress before reconnecting upgrade client\n}","typeGuard":"function isUpgrading(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  if (isUpgradeInProgress(err)) {\n    await delay(retryInterval)\n    return retryUpgradeConnection(wsUuid)\n  }\n  throw err\n}","preventionTips":["Ensure exactly one upgrade client per workspace; serialize upgrade attempts with a lock.","Make upgrade clients idempotent so a mid-upgrade reconnect resumes rather than restarts.","Alert if maintenance stays true longer than the expected upgrade duration (stuck upgrade).","Monitor upgrade client network stability; reconnects mid-upgrade are the main trigger."],"tags":["upgrade","maintenance-mode","reconnect","workspace"],"backgroundTag":"upgrade-reconnect","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}