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
handleRequest authenticates the caller by resolving the token with the account service's getLoginInfoByToken. Even when a token is present, the returned login info must be a workspace login (validated by isWorkspaceLoginInfo). If the token belongs to a non-workspace principal (e.g. a regular user/account token or service token) or the info is incomplete, the handler throws ApiError(401, "Couldn't find workspace with the provided token").
Source
Thrown at services/print/pod-print/src/server.ts:125
type AsyncRequestHandler = (
req: Request,
res: Response,
wsIds: WorkspaceIds,
wsLoginInfo: WorkspaceLoginInfo,
next: NextFunction
) => Promise<void>
const handleRequest = async (
fn: AsyncRequestHandler,
req: Request,
res: Response,
next: NextFunction
): Promise<void> => {
try {
const token = extractToken(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")
}
const wsIds = {
uuid: wsLoginInfo.workspace,
dataId: wsLoginInfo.workspaceDataId,
url: wsLoginInfo.workspaceUrl
}
await fn(req, res, wsIds, wsLoginInfo, 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)
}
function parsePrintOptions (query: Request['query']): PrintOptions {View on GitHub (pinned to 63e28dc964)
Solutions
- Obtain a workspace-scoped token (workspace login info) for the target workspace and use it in the Authorization header/query/cookie
- Verify the token was issued by the same accounts instance the print service is configured against (config.AccountsUrl)
- Check that the workspace still exists and is active; re-login to refresh the token
- Log/inspect getLoginInfoByToken output to confirm which field is missing (workspace, workspaceDataId, workspaceUrl)
Example fix
// before const token = userAccountToken // user token, not workspace token const wsLoginInfo = await getAccountClient(token).getLoginInfoByToken() // not a WorkspaceLoginInfo // after const token = await obtainWorkspaceToken(workspaceUrl) // workspace-scoped token const wsLoginInfo = await getAccountClient(token).getLoginInfoByToken() if (!isWorkspaceLoginInfo(wsLoginInfo)) throw new ApiError(401, 'Token is not workspace-scoped')
Defensive patterns
Strategy: validation
Validate before calling
// confirm the token resolves to workspace login info before calling print endpoints
const info = await getAccountClient(token).getLoginInfoByToken()
if (!isWorkspaceLoginInfo(info)) {
throw new Error('Current token is not workspace-scoped; obtain a workspace token for the print service')
} Type guard
function isWorkspaceLoginInfo(x: unknown): x is WorkspaceLoginInfo {
return x != null && typeof x === 'object' &&
typeof (x as any).workspace === 'string' &&
typeof (x as any).workspaceDataId === 'string' &&
typeof (x as any).workspaceUrl === 'string'
} Try / catch
try {
const res = await fetch(printUrl, { headers: { Authorization: `Bearer ${workspaceToken}` } })
if (res.status === 401) {
// token is valid auth but not workspace-scoped, or workspace gone — re-acquire a workspace token
workspaceToken = await acquireWorkspaceToken(currentWorkspace)
return fetch(printUrl, { headers: { Authorization: `Bearer ${workspaceToken}` } })
}
return res
} catch (err) {
throw new Error(`Print request failed: ${(err as Error).message}`)
} Prevention
- Use workspace-scoped tokens (not personal account tokens) for print endpoints
- Ensure the print service and your token issuer point at the same AccountsUrl
- Re-login after workspace deletion/rename to get a fresh valid token
- Keep environment tokens separate: never use dev tokens against the production accounts service
When it happens
Trigger: Calling a print endpoint with a valid but non-workspace token (user login token instead of a workspace token); a token for a deleted/archived workspace so getLoginInfoByToken returns info without workspace fields; a service token with no workspace attached.
Common situations: Using a personal account JWT instead of the workspace-scoped token the print service requires; workspace removed or renamed after the token was issued; copying a token from the wrong environment (dev token against prod account service); token signed for a different AccountsUrl instance.
Related errors
- Couldn't find workspace with the provided token
- platform.status.Unauthorized
- Unauthorized
- Invalid workspace login info by token
- platform.status.BadRequest
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/a854efc095772ae9.
Report an issue: GitHub.