hcengineering/platform · error · PlatformError

account.status.PersonNotFound

account.status.PersonNotFound

Error message

PersonNotFound

What it means

Thrown when the primary person uuid passed to the persons-merge flow does not match any document in db.person. Authority verification has passed; the merge target simply does not exist. The error payload includes the missing person uuid.

Source

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

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

  if (primaryPerson === secondaryPerson) {
    // Nothing to do
    return false
  }

  // This is a predicate the merge dialog polls, so an unauthorized caller is answered
  // rather than thrown at. mergeSpecifiedPersons below enforces the same rules.
  if (!(await verifyMergePersonsAuthority(db, decodedToken, primaryPerson, secondaryPerson, false))) {
    return false
  }

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

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

  // TODO: support checking if the source person is merged already

  // Merge social ids. Re-wire the secondary person social ids to the primary person.
  // Keep their ids. This way all PersonIds inside the workspaces will remain the same.
  const verifiedSecondaryIds = await db.socialId.find({ personUuid: secondaryPerson, verifiedOn: { $ne: null } })

  return verifiedSecondaryIds.length === 0
}

export async function mergeSpecifiedPersons (
  ctx: MeasureContext,

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Verify the primary person exists (db.person.findOne({uuid})) before merging
  2. Re-fetch the correct uuid from the source system
  3. Point the operation at the environment where the person actually exists

Example fix

// before
await mergePersons(token, { primaryPerson: staleUuid, secondaryPerson: okUuid })
// after
const p = await db.person.findOne({ uuid: staleUuid })
if (!p) throw new Error(`unknown primary person ${staleUuid}`)
await mergePersons(token, { primaryPerson: staleUuid, secondaryPerson: okUuid })
Defensive patterns

Strategy: validation

Validate before calling

const primary = await db.person.findOne({ uuid: primaryPerson })
if (primary == null) throw new Error(`primary person ${primaryPerson} not found`)

Type guard

function primaryExists(p: Person | null, uuid: string): p is Person {
  return p != null && p.uuid === uuid
}

Try / catch

try {
  await mergePersons(token, { primaryPerson, secondaryPerson })
} catch (err) {
  if ((err as PlatformError).props?.code === platform.status.PersonNotFound) {
    console.error('primary person missing; verify uuid and environment')
  } else throw err
}

Prevention

When it happens

Trigger: Calling the merge operation with a primaryPerson uuid that was deleted, mistyped, or belongs to another database; also hit when merge is attempted with a fabricated/stale uuid after authority checks were bypassed via verifyMergePersonsAuthority(..., false).

Common situations: Merging against an already-deleted account; copying uuids between environments (dev vs prod); referencing a person from a workspace dump that was never imported into the person collection.

Related errors


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