hcengineering/platform · error · PlatformError

BadRequest

BadRequest

Error message

BadRequest

What it means

This BadRequest error is thrown during grant-based sign-up when neither the grant nor the identity info supplies a first name. The operation requires firstName to create the person record, so it fails fast before any DB writes.

Source

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

  }

  return { account, socialId }
}

export async function signUpByGrant (
  ctx: MeasureContext,
  db: AccountDB,
  branding: Branding | null,
  accountUuid: AccountUuid,
  grant: PermissionsGrant,
  info?: LoginInfoRequestData
): Promise<{ account: AccountUuid, socialId: PersonId }> {
  const firstName = grant.firstName ?? info?.firstName
  const lastName = grant.lastName ?? info?.lastName

  if (firstName == null || firstName === '') {
    ctx.error('First name is required for grant sign up', { grant, info })
    throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
  }

  const existingAccount = await db.account.findOne({ uuid: accountUuid })

  if (existingAccount != null) {
    ctx.error('An account with the provided uuid already exists', { accountUuid })
    throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountAlreadyExists, {}))
  }

  const existingPerson = await db.person.findOne({ uuid: accountUuid })

  if (existingPerson == null) {
    await db.person.insertOne({ uuid: accountUuid, firstName, lastName: lastName ?? '' })
  }

  // If there's no account there should be no Huly social id associated with the person if it existed
  // also, there should be no confirmed social ids associated
  // so we can safely proceed to account creation

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Ensure the sign-up grant or identity info includes a non-empty firstName
  2. Fall back to a default name (e.g. derive from email or ask the user) when the provider omits it
  3. Validate the profile payload before calling the sign-up function

Example fix

// before
await doGrantSignup(ctx, db, grant, info, accountUuid)
// after
const firstName = grant.firstName ?? info?.firstName ?? email.split('@')[0]
await doGrantSignup(ctx, db, { ...grant, firstName }, info, accountUuid)
Defensive patterns

Strategy: validation

Validate before calling

const firstName = grant.firstName ?? info?.firstName
if (firstName == null || firstName === '') throw new Error('First name is required for grant sign up')

Type guard

function hasFirstName(g: { firstName?: string | null }, i?: { firstName?: string | null } | null): g is { firstName: string } { return (g.firstName ?? i?.firstName ?? '') !== '' }

Try / catch

try { await doGrantSignup(ctx, db, grant, info, accountUuid) } catch (err) { if (isStatus(err, platform.status.BadRequest)) { /* prompt user for a name */ } else throw err }

Prevention

When it happens

Trigger: Calling the grant sign-up function (server/account/src/utils.ts:735) where grant.firstName and info?.firstName are both null/undefined/'' for the accountUuid.

Common situations: OAuth providers that omit given_name in their profile payload; incomplete social profiles (no name shared); grant created programmatically with only email.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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