phacility/phabricator · error · Exception

Phone number ("%s") is not in a recognized format: expected

Error message

Phone number ("%s") is not in a recognized format: expected a US number like "(555) 555-5555", or an international number like "+55 5555 555555".

What it means

PhabricatorPhoneNumber strips every non-digit character, then requires the remaining digits to match ^[1-9]\d{9,14}\z: 10 to 15 digits with no leading zero. A raw number without a leading '+' whose digits total exactly 10 is assumed to be US and gets '1' prefixed. Any input that does not survive this normalization (too few/many digits, leading zero, empty) throws a plain Exception from the constructor. It is used wherever Phabricator stores or routes SMS phone numbers.

Source

Thrown at src/applications/metamta/message/PhabricatorPhoneNumber.php:12

<?php

final class PhabricatorPhoneNumber
  extends Phobject {

  private $number;

  public function __construct($raw_number) {
    $number = preg_replace('/[^\d]+/', '', $raw_number);

    if (!preg_match('/^[1-9]\d{9,14}\z/', $number)) {
      throw new Exception(
        pht(
          'Phone number ("%s") is not in a recognized format: expected a '.
          'US number like "(555) 555-5555", or an international number '.
          'like "+55 5555 555555".',
          $raw_number));
    }

    // If the number didn't start with "+" and has has 10 digits, assume it is
    // a US number with no country code prefix, like "(555) 555-5555".
    if (!preg_match('/^[+]/', $raw_number)) {
      if (strlen($number) === 10) {
        $number = '1'.$number;
      }
    }

    $this->number = $number;
  }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Store numbers in E.164 format with a leading '+' (e.g. +15555551234).
  2. For US numbers without '+', include the area code so the digit count is exactly 10.
  3. Trim extension suffixes and formatting noise before constructing PhabricatorPhoneNumber.
  4. Validate at input time (same regex the class uses) so bad data never reaches storage.

Example fix

// before
$number = new PhabricatorPhoneNumber('555-1234');
// throws: not in a recognized format

// after
$number = new PhabricatorPhoneNumber('+1 (555) 555-1234');
Defensive patterns

Strategy: validation

Validate before calling

// Apply the class's own normalization rules before constructing:
function is_valid_phone_number($raw) {
  $digits = preg_replace('/[^\d]+/', '', $raw);
  return (bool)preg_match('/^[1-9]\d{9,14}\z/', $digits);
}
if (!is_valid_phone_number($raw)) {
  // reject at input time with a user-facing message
}

Try / catch

try {
  $number = new PhabricatorPhoneNumber($raw);
} catch (Exception $ex) {
  // surface the message to the user and re-prompt for E.164 input
}

Prevention

When it happens

Trigger: Constructing with a 7-digit local number ('555-1234'); numbers with a leading zero after stripping; empty or purely non-numeric input; numbers longer than 15 digits (e.g. with an extension appended); non-US numbers supplied without a country code.

Common situations: SMS mailer integrations (user phone numbers from account settings) fed with placeholder test data; users entering local-format numbers; forms that do not validate before saving, so the failure surfaces later at send/lookup time.

Related errors


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