hcengineering/platform · error · PlatformError
AccountNotFound
AccountNotFound
Error message
platform.status.AccountNotFound
What it means
Thrown by the account service when looking up an account by a normalized email during email-based social ID operations (e.g. email join/invite flows). The email social ID resolved to a personUuid, but no account exists for that UUID in the database, indicating dangling or inconsistent social-ID data. The Status carries the missing account UUID.
Source
Thrown at server/account/src/operations.ts:1519
const normalizedEmail = cleanEmail(email)
ctx.info('Requesting password reset', { email, normalizedEmail })
const emailSocialId = await getEmailSocialId(db, normalizedEmail)
if (emailSocialId == null) {
ctx.error('Email social id not found', { email, normalizedEmail })
throw new PlatformError(
new Status(Severity.ERROR, platform.status.SocialIdNotFound, { value: email, type: SocialIdType.EMAIL })
)
}
const account = await getAccount(db, emailSocialId.personUuid as AccountUuid)
if (account == null) {
ctx.info('Account not found', { email, normalizedEmail })
throw new PlatformError(
new Status(Severity.ERROR, platform.status.AccountNotFound, { account: emailSocialId.personUuid })
)
}
const { mailURL, mailAuth } = getMailUrl()
const front = getFrontUrl(branding)
const token = generateToken(account.uuid, undefined, {
restoreEmail: normalizedEmail
})
const link = concatLink(front, `/login/recovery?id=${token}`)
const lang = branding?.language
const text = await translate(accountPlugin.string.RecoveryText, { link }, lang)
const html = await translate(accountPlugin.string.RecoveryHTML, { link }, lang)
const subject = await translate(accountPlugin.string.RecoverySubject, {}, lang)
const response = await fetch(concatLink(mailURL, '/send'), {View on GitHub (pinned to 63e28dc964)
Solutions
- Check the account exists for the personUuid (getAccount) before invoking the email-based operation.
- Clean up orphaned socialId documents whose personUuid has no matching account.
- If migrating/restoring workspaces, ensure accounts were migrated to the same instance first.
- Re-trigger the signup flow so the account is created before joining.
Example fix
// before: assume social id implies account
const account = await getAccount(db, emailSocialId.personUuid as AccountUuid)
await join(ctx, emailSocialId.personUuid)
// after: guard first
const account = await getAccount(db, emailSocialId.personUuid as AccountUuid)
if (account == null) {
await signupAndCreateAccount(ctx, email)
} Defensive patterns
Strategy: validation
Validate before calling
const account = await getAccount(db, emailSocialId.personUuid as AccountUuid)
if (account == null) {
// recreate account or clean up orphaned socialId before proceeding
} Type guard
function accountExists(a: Account | null | undefined): a is Account { return a != null } Try / catch
try {
await joinByEmail(ctx, email)
} catch (err) {
if (err instanceof PlatformError && err.status.code === platform.status.AccountNotFound) {
await cleanupOrphanedSocialId(email); await reSignup(email)
} else throw err
} Prevention
- Delete socialId records together with the account in the same transaction.
- After restores/migrations, run an orphaned-socialId consistency check.
- Log and monitor AccountNotFound occurrences to catch data drift early.
When it happens
Trigger: Calling an account operation (e.g. joinByEmailSocialId) where db social ID lookup for SocialIdType.EMAIL yields a personUuid whose account row was deleted or never created.
Common situations: Account deletion left orphaned social ID records; workspace backups/restores referencing accounts from another instance; email reused across regions; race between account creation and email verification.
Related errors
- SocialIdNotFound
- account.status.Forbidden
- SocialIdNotFound
- Social ID is missing
- Training #${request.attachedTo} not found
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/8ff40bdd5a52cb46.
Report an issue: GitHub.