phacility/phabricator · error · PhabricatorApplicationTransactionValidationException

This email address is already in use.

Error message

This email address is already in use.

What it means

The application-email editor writes rows to the application email table, which enforces a UNIQUE key on address. MySQL raised a duplicate-key error and Lisk routed it to didCatchDuplicateKeyException(), which converts it into a PhabricatorApplicationTransactionValidationException attached to the TYPE_ADDRESS field. The address you tried to create or rename to already exists on another application email record.

Source

Thrown at src/applications/metamta/editor/PhabricatorMetaMTAApplicationEmailEditor.php:165

        break;
    }

    return $errors;
  }

  protected function didCatchDuplicateKeyException(
    PhabricatorLiskDAO $object,
    array $xactions,
    Exception $ex) {

    $errors = array();
    $errors[] = new PhabricatorApplicationTransactionValidationError(
      PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS,
      pht('Duplicate'),
      pht('This email address is already in use.'),
      null);

    throw new PhabricatorApplicationTransactionValidationException($errors);
  }


}

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. List existing application emails first (the application's Email Addresses panel, or PhabricatorMetaMTAApplicationEmailQuery) and edit or reuse the existing record instead of creating a duplicate.
  2. Use a unique address per application (reviews@, tasks@, commits@...).
  3. If you genuinely need to move an address to another application, delete it from the old application first, then create it on the new one.

Example fix

// before: create blindly
$email = PhabricatorMetaMTAApplicationEmail::initializeNewEmail($viewer)
  ->setAddress('reviews@example.com');
$editor->applyTransactions($email, $xactions);

// after: pre-check uniqueness, reuse when present
$existing = id(new PhabricatorMetaMTAApplicationEmailQuery())
  ->setViewer($viewer)
  ->withAddresses(array('reviews@example.com'))
  ->executeOne();
if ($existing) {
  $email = $existing; // edit instead of create
}
$editor->applyTransactions($email, $xactions);
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check address uniqueness before saving.
$existing = id(new PhabricatorMetaMTAApplicationEmailQuery())
  ->setViewer($viewer)
  ->withAddresses(array($address))
  ->executeOne();
if ($existing && $existing->getID() != $email->getID()) {
  // reuse $existing or pick another address
}

Try / catch

try {
  $editor->applyTransactions($email, $xactions);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
  foreach ($ex->getErrors() as $error) {
    if ($error->getType() === PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS) {
      // show 'address already in use' next to the address field
    }
  }
}

Prevention

When it happens

Trigger: Creating a PhabricatorMetaMTAApplicationEmail (or editing one's address via the editor) to a value already owned by another record - e.g. adding differential@example.com while a Maniphest or Differential application email already uses that exact address; also two simultaneous creations of the same address.

Common situations: Configuring inbound addresses for multiple applications and reusing one address; migrating/importing application email config on top of existing rows; race conditions when two admins add the same address at once.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/90af48509005bab5. Report an issue: GitHub.