hcengineering/platform · error · PlatformError
platform.status.SocialIdAlreadyExists
platform.status.SocialIdAlreadyExists
Error message
throw new PlatformError(
new Status(Severity.ERROR, platform.status.SocialIdAlreadyExists, { value: email, type: SocialIdType.EMAIL })
) What it means
addEmailSocialId checks whether the normalized email already exists as a verified EMAIL social id. Per the documented policy, if the social id exists and is verified — for this or another account — it throws platform.status.SocialIdAlreadyExists carrying the value and type. Unverified duplicates are reclaimed/moved instead of erroring; only verified ones collide.
Source
Thrown at server/account/src/operations.ts:2905
if (account == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotFound, { account }))
}
const normalizedEmail = normalizeValue(email)
const existing = await db.socialId.findOne({ type: SocialIdType.EMAIL, value: normalizedEmail })
// This schema should be applied to all types in general, they should only differ by the verification process.
// If none exists, create a new one and proceed to verification
// If exists only for person without account - will be able to merge person to the account, proceed to verification
// If exists for this account but not verified - proceed to verification right away
// If exists for this account and verified - throw an error (already exists)
// If exists for another account and not verified - will move only this id to the current account, proceed to verification
// If exists for another account and verified - throw an error for now, support merge accounts later, maybe through a different procedure
let targetSocialId: SocialId
if (existing != null) {
if (existing.verifiedOn != null) {
throw new PlatformError(
new Status(Severity.ERROR, platform.status.SocialIdAlreadyExists, { value: email, type: SocialIdType.EMAIL })
)
}
targetSocialId = existing
} else {
const newSocialId = {
type: SocialIdType.EMAIL,
value: normalizedEmail,
personUuid: account
}
const _id = await db.socialId.insertOne(newSocialId)
targetSocialId = { ...newSocialId, _id, key: buildSocialIdString(newSocialId) }
}
return await sendOtp(ctx, db, branding, targetSocialId)
}
async function addHulyAssistantSocialId (View on GitHub (pinned to 63e28dc964)
Solutions
- Sign in with the existing account that owns this verified email instead of adding it to another account.
- Choose a different, unregistered email address.
- If the old account is yours and unreachable, use password recovery or account merge/support procedure, then retry.
- Verify with an email lookup which account owns the address before attempting to link it.
Example fix
// before
await accountClient.addEmailSocialId(token, { email: 'user@example.com' }) // already verified elsewhere
// after
const owner = await findAccountByEmail('user@example.com')
if (owner != null) {
showNotice('This email is already registered. Sign in or recover that account.')
return
}
await accountClient.addEmailSocialId(token, { email: 'user@example.com' }) Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check whether the email is already registered/verified elsewhere
const existing = await lookupAccountByEmail(email)
if (existing != null && existing.verified) {
showNotice('This email is already registered. Sign in instead.')
return
} Type guard
function isUnclaimed (s: SocialId | null): s is null | (SocialId & { verifiedOn: null }) {
return s == null || s.verifiedOn == null
} Try / catch
try {
await accountClient.addEmailSocialId(token, { email })
} catch (err) {
if (err instanceof PlatformError && err.status.code === platform.status.SocialIdAlreadyExists) {
showError('This email is already verified on another account. Sign in with it or use a different email.')
} else throw err
} Prevention
- Check email availability before offering the add-email flow in the UI.
- Prompt users to sign in with existing verified emails rather than re-linking.
- Route duplicate-email cases to account recovery/merge flows.
- Normalize emails (lowercase/trim) consistently to avoid false duplicates and missed ones.
When it happens
Trigger: Adding an email that is already verified on another account (email reused after old signup), or re-adding an email the same account already verified. Also duplicate signup flows racing where one verification completed first.
Common situations: User forgot an old account with that email exists; trying to link a work email already bound to a colleague's account; test emails reused across accounts; password-manager autofill filling an already-registered email.
Related errors
- Workspace not found
- platform.status.SocialIdNotFound
- AccountNotFound
- SocialIdNotFound
- account.status.Forbidden
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/381acfab9cb4c6fa.
Report an issue: GitHub.