{"record":{"id":"add214015a8761b9","repo":"hcengineering/platform","slug":"couldn-t-find-workspace-with-the-provided-token","errorCode":null,"errorMessage":"Couldn't find workspace with the provided token","messagePattern":"Couldn't find workspace with the provided token","errorType":"http","errorClass":"ApiError","httpStatus":401,"severity":"error","filePath":"services/export/pod-export/src/server.ts","lineNumber":236,"sourceCode":"  req: Request,\n  res: Response,\n  wsIds: WorkspaceIds,\n  token: string,\n  socialId: PersonId,\n  next: NextFunction\n) => Promise<void>\n\nconst handleRequest = async (\n  fn: AsyncRequestHandler,\n  req: Request,\n  res: Response,\n  next: NextFunction\n): Promise<void> => {\n  try {\n    const token = retrieveToken(req.headers, req.query)\n    const wsLoginInfo = await getAccountClient(token).getLoginInfoByToken()\n    if (!isWorkspaceLoginInfo(wsLoginInfo)) {\n      throw new ApiError(401, \"Couldn't find workspace with the provided token\")\n    }\n    if (wsLoginInfo.socialId === undefined) {\n      throw new ApiError(401, 'Social ID is missing')\n    }\n    const wsIds = {\n      uuid: wsLoginInfo.workspace,\n      dataId: wsLoginInfo.workspaceDataId,\n      url: wsLoginInfo.workspaceUrl\n    }\n    await fn(req, res, wsIds, token, wsLoginInfo.socialId, next)\n  } catch (err: unknown) {\n    next(err)\n  }\n}\n\nconst wrapRequest = (fn: AsyncRequestHandler) => (req: Request, res: Response, next: NextFunction) => {\n  // eslint-disable-next-line @typescript-eslint/no-floating-promises\n  handleRequest(fn, req, res, next)","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/export/pod-export/src/server.ts#L218-L254","documentation":"The pod-export service authenticates every request by calling getLoginInfoByToken() with the token extracted from headers/query, then validates the result with isWorkspaceLoginInfo(). When the account service does not recognize the token or returns a payload that is not valid workspace login info, the request is rejected with this 401 ApiError. It means the caller did not present a usable workspace-scoped token.","triggerScenarios":"POST/GET to an export endpoint where retrieveToken(req.headers, req.query) yields a token that is expired, revoked, belongs to a non-workspace account, or is absent/malformed so getAccountClient(token).getLoginInfoByToken() returns data failing isWorkspaceLoginInfo.","commonSituations":"Using an expired workspace token in a script; copying the wrong token type (e.g. a personal/service token instead of a workspace token); passing the token as a query param that got URL-truncated; environment pointing the account client at the wrong AccountsUrl.","solutions":["Generate a fresh workspace token and retry the request with it.","Verify the token is sent in the header (or query) key retrieveToken expects and is not truncated by shell/URL encoding.","Confirm the service is configured with the correct AccountsUrl for your environment (dev/prod) so the token is validated against the right account service.","Log wsLoginInfo (without secrets) to see whether the account call returns an error object rather than workspace info."],"exampleFix":"// before\ncurl -H 'Authorization: Bearer OLD_TOKEN' /export?format=json\n// after\ncurl -H 'Authorization: Bearer NEWLY_ISSUED_WORKSPACE_TOKEN' /export?format=json","handlingStrategy":"validation","validationCode":"if (typeof token !== 'string' || token.length === 0) { throw new Error('Refusing to call export without a workspace token') }","typeGuard":"function isWorkspaceLoginInfo(v: unknown): v is { socialId: string | undefined; workspace: string; workspaceDataId: string; workspaceUrl: string } {\n  return typeof v === 'object' && v !== null && 'workspace' in v && typeof (v as any).workspace === 'string'\n}","tryCatchPattern":"try {\n  await exportWorkspace(params)\n} catch (e) {\n  if (e instanceof ApiError && e.status === 401) { await refreshToken(); return exportWorkspace(params) }\n  throw e\n}","preventionTips":["Refresh workspace tokens before long-running jobs; handle 401 by re-authenticating once.","Store tokens in env/secrets manager, not in URLs that can be truncated or logged.","Verify the token type (workspace vs account) before calling export endpoints."],"tags":["auth","http-401","token","workspace"],"backgroundTag":"invalid-auth-token","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}