phacility/phabricator · error · Exception

Version name "%s" is not valid: version names may not start

Error message

Version name "%s" is not valid: version names may not start or end with a period or hyphen.

What it means

Thrown by PhabricatorPackagesVersion::assertValidVersionName() when a version name starts or ends with a period or hyphen (checked with /^[.-]|[.-]$/). Such names would be ambiguous and sort oddly in the package version list, so '.1.0', '1.0-', or '-beta' are rejected even though their character set is otherwise legal.

Source

Thrown at src/applications/packages/storage/PhabricatorPackagesVersion.php:89

    if ($length > $max_length) {
      throw new Exception(
        pht(
          'Version name "%s" is not valid: version names must not be '.
          'more than %s characters long.',
          $value,
          new PhutilNumber($max_length)));
    }

    if (!preg_match('/^[A-Za-z0-9.-]+\z/', $value)) {
      throw new Exception(
        pht(
          'Version name "%s" is not valid: version names may only contain '.
          'latin letters, digits, periods, and hyphens.',
          $value));
    }

    if (preg_match('/^[.-]|[.-]$/', $value)) {
      throw new Exception(
        pht(
          'Version name "%s" is not valid: version names may not start or '.
          'end with a period or hyphen.',
          $value));
    }
  }


/* -(  PhabricatorSubscribableInterface  )----------------------------------- */


  public function isAutomaticallySubscribed($phid) {
    return false;
  }


/* -(  Policy Interface  )--------------------------------------------------- */

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Trim leading and trailing periods/hyphens from the name before saving.
  2. Run the sanitizer and the trim as one step: preg_replace then trim('.-').
  3. Add the same edge check client-side so users see the rule before submit.

Example fix

// before
$name = preg_replace('/[^A-Za-z0-9.-]+/', '-', '-1.0.0-rc+2');
// $name is now '-1.0.0-rc-2-', which throws

// after
$name = preg_replace('/[^A-Za-z0-9.-]+/', '-', '-1.0.0-rc+2');
$name = trim($name, '.-');
// $name is now '1.0.0-rc-2'
PhabricatorPackagesVersion::assertValidVersionName($name);
Defensive patterns

Strategy: validation

Validate before calling

$name = preg_replace('/[^A-Za-z0-9.-]+/', '-', $raw_name);
$name = trim($name, '.-');
PhabricatorPackagesVersion::assertValidVersionName($name);

Type guard

function has_no_edge_separators($name) {
  return is_string($name)
    && preg_match('/^[.-]|[.-]$/', $name) !== 1;
}

Try / catch

try {
  PhabricatorPackagesVersion::assertValidVersionName($name);
} catch (Exception $ex) {
  $errors[] = $ex->getMessage();
}

Prevention

When it happens

Trigger: Creating a version whose name was produced by trimming or sanitization that left a leading/trailing separator, e.g. stripping '+1' from '1.0.0+' or '-rc' from '1.0.0-' via a regex that leaves the edge character behind.

Common situations: Automated sanitizers that replace forbidden characters with hyphens and forget to trim the edges; importing tags like '-WIP-' or trailing-dot typos.

Related errors


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