hcengineering/platform · error · PlatformError

InternalServerError

InternalServerError

Error message

InternalServerError

What it means

Near the end of selectWorkspace (server/account/src/utils.ts), after role, account and workspace-status checks pass, the service loads the corresponding person document (db.person.findOne({ uuid: accountUuid })). If it is null the internal invariant 'every account with a workspace role has a person record' is broken, so it throws InternalServerError. This is a data-integrity failure inside the account database, not a client mistake.

Source

Thrown at server/account/src/utils.ts:901

    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 })

      throw new PlatformError(new Status(Severity.ERROR, platform.status.WorkspaceNotFound, { workspaceUrl }))
    }
  }

  const person = await db.person.findOne({ uuid: accountUuid })
  if (person == null) {
    throw new PlatformError(new Status(Severity.ERROR, platform.status.InternalServerError, {}))
  }

  return {
    account: accountUuid,
    token: generateToken(accountUuid, workspace.uuid, extra, undefined, {
      grant,
      sub,
      exp,
      nbf
    }),
    endpoint: getEndpoint(workspace.uuid, workspace.region, getKind(workspace.region)),
    workspace: workspace.uuid,
    workspaceUrl: workspace.url,
    workspaceDataId: workspace.dataId,
    allowGuestSignUp: workspace.allowReadOnlyGuest && workspace.allowGuestSignUp,
    role
  }
}

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Inspect the person collection for the missing uuid and restore/recreate the person record (firstName/lastName) matching the account.
  2. Restore DB consistency from a backup or run a repair script that re-creates person rows for orphan accounts.
  3. Audit any custom tooling/migrations that delete or move account data so person and account records stay in sync.
  4. Report to the platform operators if this occurs on a managed instance — it signals internal data corruption.

Example fix

// before: orphan account with no person row -> InternalServerError on select
await accountClient.selectWorkspace(token, url)

// after: repair the DB first (admin side)
await db.person.insertOne({ uuid: orphanAccountUuid, firstName: 'Jane', lastName: 'Doe' })
await db.account.findOne({ uuid: orphanAccountUuid }) // ensure account row exists
// then retry selection
Defensive patterns

Strategy: try-catch

Validate before calling

// admin-side precheck that the account's person row exists
const person = await db.person.findOne({ uuid: accountUuid })
if (person == null) {
  throw new Error('Person record missing for account; repair DB before selecting workspace')
}

Type guard

function personExists(p: { uuid: string } | null | undefined): p is { uuid: string } {
  return p != null
}

Try / catch

try {
  await accountClient.selectWorkspace(token, url)
} catch (e) {
  if ((e as PlatformError).status.code === platform.status.InternalServerError) {
    reportToOps('selectWorkspace invariant violated: person record missing')
  } else throw e
}

Prevention

When it happens

Trigger: db.person.findOne({ uuid: accountUuid }) returns null although the account passed earlier checks — e.g. the person record was deleted while account/role rows remain, a backup was partially restored, or a migration wrote accounts/roles without persons.

Common situations: Partial DB restores, custom scripts removing person documents, region-merge tooling copying account data without person data, corrupted workspaces after failed migrations.

Related errors


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