hcengineering/platform · error · PlatformError

account.status.BadRequest

account.status.BadRequest

Error message

BadRequest

What it means

Thrown when the account-deletion handler receives a null, undefined, or empty string uuid. The admin check has already passed; this validates that the target account identifier is present before calling db.deleteAccount.

Source

Thrown at server/account/src/operations.ts:3039

export async function deleteAccount (
  ctx: MeasureContext,
  db: AccountDB,
  branding: Branding | null,
  token: string,
  params: { uuid?: AccountUuid }
): Promise<void> {
  const { extra } = decodeTokenVerbose(ctx, token)

  const isAdmin = extra?.admin === 'true'

  if (!isAdmin) {
    throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
  }

  const { uuid } = params

  if (uuid == null || uuid === '') {
    throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
  }

  await db.deleteAccount(uuid)
  await db.accountEvent.insertOne({
    accountUuid: uuid,
    eventType: AccountEventType.ACCOUNT_DELETED,
    time: Date.now()
  })
}

// Social ids that resolve to an account on their own, and therefore hand over the ability to
// authenticate as its owner once they are re-pointed. Password recovery and OTP login look an
// account up by social id value alone (see requestPasswordReset, loginOtp).
const loginCapableSocialTypes = [SocialIdType.EMAIL, SocialIdType.HULY]

/**
 * Merging re-points the secondary person's social ids onto the primary person, so an unrestricted
 * caller could both absorb the identifiers of a person they do not own and inject their own

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Resolve and pass a non-empty account uuid in params
  2. Guard the call site against null/empty uuid before invoking
  3. Log/inspect the upstream source of the uuid to find why it is empty

Example fix

// before
await removeAccount(adminToken, account?.uuid) // may be undefined
// after
if (!account?.uuid) throw new Error('account uuid missing')
await removeAccount(adminToken, account.uuid)
Defensive patterns

Strategy: validation

Validate before calling

if (uuid == null || uuid === '') throw new Error('account uuid is required')

Type guard

function hasUuid(a: { uuid?: string | null } | null | undefined): a is { uuid: string } {
  return typeof a?.uuid === 'string' && a.uuid !== ''
}

Try / catch

try {
  await removeAccount(adminToken, uuid)
} catch (err) {
  if ((err as PlatformError).props?.code === platform.status.BadRequest) {
    console.error('missing or empty uuid in request params')
  } else throw err
}

Prevention

When it happens

Trigger: Calling the delete-account operation with params.uuid missing, null, or '' — typically a caller that did not resolve the account uuid before invoking the operation.

Common situations: Upstream code passes an unpopulated record field; a lookup of the uuid failed silently and null was forwarded; API clients omit the uuid field in the request payload.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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