hcengineering/platform · error · PlatformError
Conflict
Conflict
Error message
Verifying new social id belonging to person w/o account but it's already verified
What it means
In validateOtp, while verifying a new email social id that belongs to a person who has no account yet, the social id turns out to already have verifiedOn set — which should be impossible at this point. The server treats it as an inconsistent state and throws Conflict.
Source
Thrown at server/account/src/operations.ts:484
if (callerAccountUuid == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotFound, {}))
}
if (targetAccount == null) {
// only person exists means there's no verified social id associated with it -> merge it to the current account
// doMergePersons will fail if there's a verified social id
await doMergePersons(db, callerAccountUuid, emailSocialId.personUuid)
// what happens to local persons referencing this person in various workspaces?
// there can be some persons but no Employees because there's no account
// we know where the person is migrated to so can update later as needed
if (emailSocialId.verifiedOn == null) {
await db.socialId.update({ _id: emailSocialId._id }, { verifiedOn: Date.now() })
} else {
// Normally, it should not be the case
ctx.warn("Verifying new social id belonging to person w/o account but it's already verified", {
emailSocialId,
callerAccountUuid
})
throw new PlatformError(new Status(Severity.ERROR, platform.status.Conflict, {}))
}
} else {
if (callerAccountUuid === targetAccount.uuid) {
if (emailSocialId.verifiedOn == null) {
await db.socialId.update({ _id: emailSocialId._id }, { verifiedOn: Date.now() })
}
} else {
if (emailSocialId.verifiedOn == null) {
// Move the target social id to current account, we can easily do this because it was not verified
await db.socialId.update(
{ _id: emailSocialId._id },
{ personUuid: callerAccountUuid, verifiedOn: Date.now() }
)
} else {View on GitHub (pinned to 63e28dc964)
Solutions
- Avoid duplicate validateOtp calls for the same social id — make the request idempotent client-side.
- If hit after a migration, correct the data: either clear verifiedOn or link an account to the person, so state matches the expected invariant.
- Retry the signup flow from the beginning to generate a fresh social id/OTP.
- Check for concurrent sessions validating the same email and serialize the flow.
Example fix
// before
await client.validateOtp(otp) // may throw Conflict on replay
// after
if (!otpValidationPending) return // already validated
try {
await client.validateOtp(otp)
otpValidationPending = false
} catch (e) {
if (isStatusError(e, platform.status.Conflict)) refreshSignupState()
else throw e
} Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
function isConflictStatus(e: unknown): boolean {
return e instanceof PlatformError && e.status.code === platform.status.Conflict
} Try / catch
try {
await client.validateOtp(otp)
} catch (e) {
if (isConflictStatus(e)) {
// already verified: treat as success or restart signup flow
restartSignupFlow()
return
}
throw e
} Prevention
- Make OTP validation idempotent — don't call validateOtp twice for the same social id.
- Prevent concurrent OTP validation from multiple sessions/tabs.
- After data migrations, verify social id verifiedOn state matches account existence.
When it happens
Trigger: Calling validateOtp with a callerAccountUuid whose person has an email social id that was already verified (verifiedOn != null) through a prior OTP validation or a migration that pre-verified ids.
Common situations: Replaying/resharing the same OTP validation request; concurrent OTP validation from two sessions; data migrations that set verifiedOn on social ids for account-less persons, breaking the assumption in this code path.
Related errors
- platform.status.AccountNotFound
- AccountNotFound
- BadRequest
- SocialIdNotFound
- platform.status.SocialIdAlreadyExists
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/661ed65d3f88dc7d.
Report an issue: GitHub.