hcengineering/platform · error · PlatformError
platform.status.AccountNotFound
platform.status.AccountNotFound
Error message
AccountNotFound
What it means
createAccessLink decodes an access token and looks up the account UUID it embeds via db.account.findOne. If no account row matches that UUID, the platform throws AccountNotFound. This means the token references an account that no longer exists (or never existed) in the database.
Source
Thrown at server/account/src/operations.ts:766
params: {
role: AccountRole
firstName?: string
lastName?: string
extra?: string
navigateUrl?: string
spaces?: string[]
notBefore?: number
expiration?: number
personalized?: boolean
}
): Promise<string> {
const { role, firstName, lastName, navigateUrl, spaces, notBefore, expiration, personalized = true } = params
const { account, workspace: workspaceUuid, extra } = decodeTokenVerbose(ctx, token)
const currentAccount = await db.account.findOne({ uuid: account })
if (currentAccount == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotFound, { account }))
}
if (workspaceUuid == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const workspace = await db.workspace.findOne({ uuid: workspaceUuid })
if (workspace == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.WorkspaceNotFound, { workspaceUuid }))
}
let extraObj: Record<string, string> | undefined
if (params.extra != null) {
try {
extraObj = JSON.parse(params.extra)
} catch (e) {
ctx.error("Invalid extra parameter, couldn't parse JSON", { extra: params.extra })View on GitHub (pinned to 63e28dc964)
Solutions
- Re-authenticate so the user gets a token minted against the current database.
- Verify the token was issued for the same environment/database you are calling (check transactor URL and DB name).
- Confirm the account row still exists: query db.account.findOne({ uuid: <account from token> }).
- If accounts are being deleted, invalidate/revoke outstanding tokens on deletion to avoid stale-token calls.
Example fix
// before: reusing an old token after DB reset const link = await client.createAccessLink(token, params) // after: re-login to obtain a token for the current DB const token = await login(email, password) const link = await client.createAccessLink(token, params)
Defensive patterns
Strategy: try-catch
Validate before calling
const payload = decodeJwt(token)
if (payload?.account == null) throw new Error('token missing account claim') Type guard
function hasAccountClaim(t: unknown): t is { account: string } {
return typeof t === 'object' && t !== null && typeof (t as any).account === 'string'
} Try / catch
try {
const link = await createAccessLink(token, params)
} catch (err) {
if (isPlatformError(err, platform.status.AccountNotFound)) {
await reauthenticate() // token references a deleted/foreign account
} else throw err
} Prevention
- Re-login instead of reusing long-lived cached tokens after account changes.
- Keep tokens environment-specific; never copy them between dev/staging/prod.
- Invalidate tokens when deleting accounts.
When it happens
Trigger: Calling createAccessLink with a token whose embedded `account` UUID is absent from db.account — e.g. the account was deleted after the token was issued, the token was minted for a different/staging database, or the token is forged/corrupted.
Common situations: Pointing a client at a fresh or restored database while reusing old tokens; account cleanup jobs deleting accounts with live tokens; copying tokens between environments (dev/prod); typos when manually crafting tokens in tests.
Related errors
- platform.status.WorkspaceNotFound
- platform.status.Unauthorized
- Workspace or account not found in token
- Unauthorized
- Invalid workspace login info by token
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/c4f066d859aaa756.
Report an issue: GitHub.