phacility/phabricator · error · Exception
Email record has invalid user PHID!
Error message
Email record has invalid user PHID!
What it means
Thrown by `bin/auth verify` when the email row exists but its userPHID column does not resolve to any real user. After loading the PhabricatorUserEmail record, the workflow queries PhabricatorPeopleQuery with that PHID; a null result raises this generic Exception (not a usage exception), because the cause is data corruption rather than operator input: an email record pointing at a missing user. The verification editor is never invoked, so nothing is written.
Source
Thrown at src/applications/auth/management/PhabricatorAuthManagementVerifyWorkflow.php:52
$email = id(new PhabricatorUserEmail())->loadOneWhere(
'address = %s',
$address);
if (!$email) {
throw new PhutilArgumentUsageException(
pht(
'No email exists with address "%s"!',
$address));
}
$viewer = $this->getViewer();
$user = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withPHIDs(array($email->getUserPHID()))
->executeOne();
if (!$user) {
throw new Exception(pht('Email record has invalid user PHID!'));
}
$editor = id(new PhabricatorUserEditor())
->setActor($viewer)
->verifyEmail($user, $email);
$console = PhutilConsole::getConsole();
$console->writeOut(
"%s\n",
pht('Done.'));
return 0;
}
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- Inspect the orphan: `SELECT e.phid, e.address, e.userPHID FROM user_email e LEFT JOIN user u ON u.phid = e.userPHID WHERE e.address = '<address>';` — the join will show NULL on the user side.
- If the user was deleted intentionally, remove the orphaned email row (or use the proper user-removal workflow to purge it), since the address can no longer be verified for anyone.
- If the user should exist, repair the userPHID to point at the correct user row and re-run `bin/auth verify <address>`.
- Audit for more orphans with `SELECT e.userPHID FROM user_email e LEFT JOIN user u ON u.phid=e.userPHID WHERE u.phid IS NULL;`.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: detect the orphan before invoking the workflow
$user = id(new PhabricatorPeopleQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs(array($email->getUserPHID()))
->executeOne();
if (!$user) {
// orphaned email row: repair or delete it before running verify
} Try / catch
try {
$err = id(new PhabricatorUserEditor())
->setActor($viewer)
->verifyEmail($user, $email);
} catch (Exception $ex) {
// 'Email record has invalid user PHID!' means data corruption:
// log it, halt the batch, and queue a manual repair of user_email.userPHID
} Prevention
- Never delete user rows with raw SQL; use Phabricator's removal workflows so dependent rows are purged.
- Periodically audit for orphaned user_email rows via LEFT JOIN on user.phid.
- Back up and verify referential integrity after imports, migrations, and restores.
When it happens
Trigger: Running `bin/auth verify <address>` where the user_email row references a PHID of a deleted/purged user, a PHID mangled by a partial import or manual SQL edit, or a user record removed while their email rows survived.
Common situations: Users were deleted with `bin/remove destroy` but orphaned user_email rows remained; a database migration or restore left referential integrity broken; someone edited user rows by hand in production.
Related errors
- You must specify the email to verify.
- You can only verify one address at a time.
- No email exists with address "%s"!
- Request parameter "%s" is not formatted properly. Expected a
- Request parameter "%s" is not formatted properly. Expected a
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/031185723f6d514d.
Report an issue: GitHub.