hcengineering/platform · error
Invalid workspace login info by token
Error message
Invalid workspace login info by token
What it means
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.
Source
Thrown at pods/server/src/server_http.ts:110
* @param port -
* @param host -
*/
export function startHttpServer (
ctx: MeasureContext,
sessions: SessionManager,
port: number,
accountsUrl: string,
externalStorage: StorageAdapter
): () => Promise<void> {
function getAccountClient (token?: string): AccountClient {
return getAccountClientRaw(accountsUrl, token)
}
async function getWorkspaceIds (token: string): Promise<WorkspaceIds> {
const wsLoginInfo = await getAccountClient(token).getLoginInfoByToken()
if (!isWorkspaceLoginInfo(wsLoginInfo)) {
throw new Error('Invalid workspace login info by token')
}
return {
uuid: wsLoginInfo.workspace,
dataId: wsLoginInfo.workspaceDataId,
url: wsLoginInfo.workspaceUrl
}
}
if (LOGGING_ENABLED) {
ctx.info('starting server on', {
port,
accountsUrl,
parallel: os.availableParallelism()
})
}
const app = express()View on GitHub (pinned to 63e28dc964)
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.
Example fix
// before
const wsIds = await getWorkspaceIds(token)
// after
const info = await getAccountClient(token).getLoginInfoByToken()
if (!isWorkspaceLoginInfo(info)) {
throw new UnauthorizedError('token is not a valid workspace token')
}
const wsIds = await getWorkspaceIds(token) Defensive patterns
Strategy: type-guard
Validate before calling
const info = await getAccountClient(token).getLoginInfoByToken()
if (!isWorkspaceLoginInfo(info)) {
// refresh token or redirect to login before calling the server
} Type guard
function isWorkspaceLoginInfo(v: any): v is WorkspaceLoginInfo {
return v != null && typeof v.workspace === 'string' &&
typeof v.workspaceDataId === 'string' && typeof v.workspaceUrl === 'string'
} Try / catch
try {
const wsIds = await getWorkspaceIds(token)
} catch (err) {
if (/Invalid workspace login info/.test(err.message)) {
await reauthenticate() // refresh token and retry once
return getWorkspaceIds(await getFreshToken())
}
throw err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- platform.status.BadRequest
- platform.status.WorkspaceNotFound
- Couldn't find workspace with the provided token
- Invalid workspace
- platform.status.Unauthorized
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/306532dee0624bce.
Report an issue: GitHub.