{"record":{"id":"306532dee0624bce","repo":"hcengineering/platform","slug":"invalid-workspace-login-info-by-token","errorCode":null,"errorMessage":"Invalid workspace login info by token","messagePattern":"Invalid workspace login info by token","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pods/server/src/server_http.ts","lineNumber":110,"sourceCode":" * @param port -\n * @param host -\n */\nexport function startHttpServer (\n  ctx: MeasureContext,\n  sessions: SessionManager,\n  port: number,\n  accountsUrl: string,\n  externalStorage: StorageAdapter\n): () => Promise<void> {\n  function getAccountClient (token?: string): AccountClient {\n    return getAccountClientRaw(accountsUrl, token)\n  }\n\n  async function getWorkspaceIds (token: string): Promise<WorkspaceIds> {\n    const wsLoginInfo = await getAccountClient(token).getLoginInfoByToken()\n\n    if (!isWorkspaceLoginInfo(wsLoginInfo)) {\n      throw new Error('Invalid workspace login info by token')\n    }\n\n    return {\n      uuid: wsLoginInfo.workspace,\n      dataId: wsLoginInfo.workspaceDataId,\n      url: wsLoginInfo.workspaceUrl\n    }\n  }\n\n  if (LOGGING_ENABLED) {\n    ctx.info('starting server on', {\n      port,\n      accountsUrl,\n      parallel: os.availableParallelism()\n    })\n  }\n\n  const app = express()","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/pods/server/src/server_http.ts#L92-L128","documentation":"getWorkspaceIds resolves the caller's workspace by fetching login info from the account service with the provided token (getLoginInfoByToken). If the returned object does not pass the isWorkspaceLoginInfo shape check, the token is invalid/expired or not tied to a workspace login, and this error is thrown.","triggerScenarios":"An HTTP request to the server with an invalid, expired, revoked, or account-level (non-workspace) token, or the account service being unreachable/misbehaving so getLoginInfoByToken returns an unexpected payload.","commonSituations":"Expired session tokens on long-lived clients, using an account token where a workspace token is required, account service version mismatch changing the login-info shape, clock skew invalidating tokens.","solutions":["Re-authenticate to obtain a fresh valid token and retry the request.","Verify the token is a workspace login token, not a plain account token.","Check account-service connectivity and that getLoginInfoByToken returns the expected workspace fields (workspace, workspaceDataId, workspaceUrl).","Confirm client and server versions agree on the login-info schema."],"exampleFix":"// before\nconst wsIds = await getWorkspaceIds(token)\n// after\nconst info = await getAccountClient(token).getLoginInfoByToken()\nif (!isWorkspaceLoginInfo(info)) {\n  throw new UnauthorizedError('token is not a valid workspace token')\n}\nconst wsIds = await getWorkspaceIds(token)","handlingStrategy":"type-guard","validationCode":"const info = await getAccountClient(token).getLoginInfoByToken()\nif (!isWorkspaceLoginInfo(info)) {\n  // refresh token or redirect to login before calling the server\n}","typeGuard":"function isWorkspaceLoginInfo(v: any): v is WorkspaceLoginInfo {\n  return v != null && typeof v.workspace === 'string' &&\n    typeof v.workspaceDataId === 'string' && typeof v.workspaceUrl === 'string'\n}","tryCatchPattern":"try {\n  const wsIds = await getWorkspaceIds(token)\n} catch (err) {\n  if (/Invalid workspace login info/.test(err.message)) {\n    await reauthenticate() // refresh token and retry once\n    return getWorkspaceIds(await getFreshToken())\n  }\n  throw err\n}","preventionTips":["Refresh tokens proactively before expiry in long-lived clients.","Use workspace-scoped tokens for workspace server calls.","Validate login-info shape before use.","Handle 401/token-invalid globally with a re-login flow."],"tags":["auth","token","workspace","http"],"backgroundTag":"invalid-workspace-token","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}