hcengineering/platform · error
Couldn't find workspace with the provided token
Error message
Couldn't find workspace with the provided token
What it means
The /signin endpoint looks up workspace login info from the account service using the provided token. If the token is valid but does not resolve to a workspace login (isWorkspaceLoginInfo returns false), the endpoint returns 400 with this fixed error string. It means the token identifies an account/user without a workspace context.
Source
Thrown at services/gmail/pod-gmail/src/main.ts:91
const endpoints: Endpoint[] = [
{
endpoint: '/signin',
type: 'get',
handler: async (req, res) => {
try {
ctx.info('Signin request received')
const token = extractToken(req.headers)
if (token === undefined) {
res.status(401).send()
return
}
const redirectURL = req.query.redirectURL as string
const accountClient = getAccountClient(token)
const wsLoginInfo = await accountClient.getLoginInfoByToken()
if (!isWorkspaceLoginInfo(wsLoginInfo)) {
res.status(400).send({ err: "Couldn't find workspace with the provided token" })
return
}
const authProvider = gmailController.getAuthProvider()
const url = authProvider.getAuthUrl(redirectURL, {
workspace: wsLoginInfo.workspace,
userId: wsLoginInfo.account
})
res.send(url)
} catch (err) {
ctx.error('signin error', { message: (err as any).message })
res.status(500).send()
}
}
},
{
endpoint: '/signin/code',
type: 'get',View on GitHub (pinned to 63e28dc964)
Solutions
- Obtain a workspace-scoped token from the account service (ensure the user has selected/signed into a workspace).
- Verify the workspace still exists and the user is a member of it.
- Re-authenticate to get a fresh token if the workspace membership changed.
Defensive patterns
Strategy: validation
Validate before calling
// before calling /signin, ensure the token is workspace-scoped:
const loginInfo = await accountClient.getLoginInfoByToken()
if (!loginInfo || !('workspace' in loginInfo) || !loginInfo.workspace) {
// token does not map to a workspace; fix authentication context first
} Type guard
function isWorkspaceLoginInfo(info: any): info is { workspace: string; account: string } {
return info != null && typeof info === 'object' &&
typeof info.workspace === 'string' && info.workspace.length > 0 &&
typeof info.account === 'string'
} Try / catch
const res = await fetch(url + '/signin', { headers })
if (res.status === 400) {
const body = await res.json()
if (body?.err === "Couldn't find workspace with the provided token") {
// prompt user to sign into a workspace and retry with a workspace-scoped token
}
} Prevention
- Use workspace-scoped tokens, not bare user tokens, for integration signin.
- Verify the user still belongs to the workspace before starting the integration flow.
- Handle deleted/reassigned workspaces by forcing re-authentication.
When it happens
Trigger: accountClient.getLoginInfoByToken() returns a login info that fails the isWorkspaceLoginInfo guard — i.e. the token belongs to a user/session not tied to a workspace (e.g. a guest or service account token, or a token whose workspace was deleted).
Common situations: Using a personal/user token instead of a workspace-scoped token; the workspace was removed after the token was issued; calling the integration signin flow from a context with no workspace selected.
Related errors
- Invalid workspace login info by token
- platform.status.BadRequest
- platform.status.WorkspaceNotFound
- Couldn't find workspace with the provided token
- You do not have write access to the target workspace. Owner
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/4926f80d49e1aedc.
Report an issue: GitHub.