hcengineering/platform · error · PlatformError
AccountNotFound
AccountNotFound
Error message
AccountNotFound
What it means
In selectWorkspace (server/account/src/utils.ts), after confirming the caller has a workspace role, the service loads the account record (db.account.findOne). If the selecting account is not the system account but no account document exists, AccountNotFound is thrown. The role lookup succeeded while the account row is missing, indicating an inconsistent account database.
Source
Thrown at server/account/src/utils.ts:875
let role = await db.getWorkspaceRole(accountUuid, workspace.uuid)
if (role == null && extra?.admin === 'true') {
role = AccountRole.Admin
}
let account = await db.account.findOne({ uuid: accountUuid })
if ((role == null || account == null) && workspace.allowReadOnlyGuest) {
accountUuid = readOnlyGuestAccountUuid
role = await db.getWorkspaceRole(accountUuid, workspace.uuid)
account = await db.account.findOne({ uuid: accountUuid })
}
if (role == null) {
ctx.error('Not a member of the workspace being selected', { workspaceUrl, accountUuid })
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
}
if (accountUuid !== systemAccountUuid && account == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotFound, {}))
}
if (accountUuid !== systemAccountUuid && meta !== undefined) {
void setTimezone(ctx, db, accountUuid, account, meta)
}
if (role === AccountRole.ReadOnlyGuest) {
if (extra == null) {
extra = {}
}
extra.readonly = 'true'
}
const wsStatus = await db.workspaceStatus.findOne({ workspaceUuid: workspace.uuid })
if (wsStatus != null) {
if (wsStatus.isDisabled && isActiveMode(wsStatus.mode)) {
ctx.error('Selecting a disabled workspace', { workspaceUrl, accountUuid })View on GitHub (pinned to 63e28dc964)
Solutions
- Recreate the missing account record for that UUID (e.g. re-register or insert via account admin tooling) so account.findOne succeeds.
- Audit consistency between person, account and workspace-role collections; repair orphans by removing stale roles or restoring the account row.
- Verify the token was issued by the same account database instance you are querying — connecting to the wrong region/DB yields missing accounts.
- If the account is truly gone, log in again to get a token bound to an existing account.
Example fix
// before: selecting with a token whose account vanished from the DB await accountClient.selectWorkspace(oldToken, workspaceUrl) // AccountNotFound // after: re-authenticate to ensure account exists server-side const fresh = await accountClient.login(email, password) await accountClient.selectWorkspace(fresh.token, workspaceUrl)
Defensive patterns
Strategy: try-catch
Validate before calling
// client-side: ensure token belongs to a live, logged-in account on this instance
const payload = decodeJwt(token)
if (payload.account !== systemAccountUuid && !await accountClient.accountExists(payload.account)) {
throw new Error('Account record missing; re-login required')
} Type guard
function hasAccount(a: { uuid: string } | null | undefined): a is { uuid: string } {
return a != null
} Try / catch
try {
await accountClient.selectWorkspace(token, url)
} catch (e) {
if ((e as PlatformError).status.code === platform.status.AccountNotFound) {
await session.logout()
await session.relogin() // token referenced an account that no longer exists
} else throw e
} Prevention
- Re-login after database restores or migrations
- Never reuse tokens across environments/regions with separate account DBs
- Keep account and person collections consistent when running custom DB tooling
- Monitor for orphaned workspace roles pointing at deleted accounts
When it happens
Trigger: Calling selectWorkspace when db.account.findOne({ uuid: accountUuid }) returns null and accountUuid !== systemAccountUuid — e.g. the person/workspace role survived but the account record was deleted, a migration partially imported accounts, or the accountUuid in the token refers to an account from another database.
Common situations: Partial restore from backup (person records restored but accounts not), cross-region/region-merge setups where an account exists in one DB but roles were copied to another, manually deleted account documents while memberships remained.
Related errors
- platform.status.InternalServerError
- platform.status.PersonNotFound
- InternalServerError
- Workspace not found
- adapter not provided: ${name}
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/4fda4ca6c5579f0f.
Report an issue: GitHub.