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

  1. Recreate the missing account record for that UUID (e.g. re-register or insert via account admin tooling) so account.findOne succeeds.
  2. Audit consistency between person, account and workspace-role collections; repair orphans by removing stale roles or restoring the account row.
  3. Verify the token was issued by the same account database instance you are querying — connecting to the wrong region/DB yields missing accounts.
  4. 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

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


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/4fda4ca6c5579f0f. Report an issue: GitHub.