hcengineering/platform · error · ApiError
Couldn't find workspace with the provided token
Error message
Couldn't find workspace with the provided token
What it means
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.
Source
Thrown at services/export/pod-export/src/server.ts:236
req: Request,
res: Response,
wsIds: WorkspaceIds,
token: string,
socialId: PersonId,
next: NextFunction
) => Promise<void>
const handleRequest = async (
fn: AsyncRequestHandler,
req: Request,
res: Response,
next: NextFunction
): Promise<void> => {
try {
const token = retrieveToken(req.headers, req.query)
const wsLoginInfo = await getAccountClient(token).getLoginInfoByToken()
if (!isWorkspaceLoginInfo(wsLoginInfo)) {
throw new ApiError(401, "Couldn't find workspace with the provided token")
}
if (wsLoginInfo.socialId === undefined) {
throw new ApiError(401, 'Social ID is missing')
}
const wsIds = {
uuid: wsLoginInfo.workspace,
dataId: wsLoginInfo.workspaceDataId,
url: wsLoginInfo.workspaceUrl
}
await fn(req, res, wsIds, token, wsLoginInfo.socialId, next)
} catch (err: unknown) {
next(err)
}
}
const wrapRequest = (fn: AsyncRequestHandler) => (req: Request, res: Response, next: NextFunction) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
handleRequest(fn, req, res, next)View on GitHub (pinned to 63e28dc964)
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.
Example fix
// before curl -H 'Authorization: Bearer OLD_TOKEN' /export?format=json // after curl -H 'Authorization: Bearer NEWLY_ISSUED_WORKSPACE_TOKEN' /export?format=json
Defensive patterns
Strategy: validation
Validate before calling
if (typeof token !== 'string' || token.length === 0) { throw new Error('Refusing to call export without a workspace token') } Type guard
function isWorkspaceLoginInfo(v: unknown): v is { socialId: string | undefined; workspace: string; workspaceDataId: string; workspaceUrl: string } {
return typeof v === 'object' && v !== null && 'workspace' in v && typeof (v as any).workspace === 'string'
} Try / catch
try {
await exportWorkspace(params)
} catch (e) {
if (e instanceof ApiError && e.status === 401) { await refreshToken(); return exportWorkspace(params) }
throw e
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- platform.status.Unauthorized
- Unauthorized
- Invalid workspace login info by token
- platform.status.BadRequest
- platform.status.WorkspaceNotFound
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/add214015a8761b9.
Report an issue: GitHub.