phacility/phabricator · error · Exception

Almanac service, device, property, network and namespace nam

Error message

Almanac service, device, property, network and namespace names may not contain hyphens adjacent to periods.

What it means

Sixth rule of AlmanacNames::validateName(): hyphens may not sit adjacent to periods, enforced by /\.-|-\./. Sequences like 'a-.b' or 'a.-b' are invalid in DNS labels, so names such as 'web-.east' or 'db.-node' are rejected.

Source

Thrown at src/applications/almanac/util/AlmanacNames.php:43

          'periods.'));
    }

    if (preg_match('/(^|\\.)\d+(\z|\\.)/', $name)) {
      throw new Exception(
        pht(
          'Almanac service, device, network, property and namespace names '.
          'may not have any segments containing only digits.'));
    }

    if (preg_match('/\.\./', $name)) {
      throw new Exception(
        pht(
          'Almanac service, device, property, network and namespace names '.
          'may not contain multiple consecutive periods.'));
    }

    if (preg_match('/\\.-|-\\./', $name)) {
      throw new Exception(
        pht(
          'Almanac service, device, property, network and namespace names '.
          'may not contain hyphens adjacent to periods.'));
    }

    if (preg_match('/--/', $name)) {
      throw new Exception(
        pht(
          'Almanac service, device, property, network and namespace names '.
          'may not contain multiple consecutive hyphens.'));
    }

    if (!preg_match('/^[a-z0-9].*[a-z0-9]\z/', $name)) {
      throw new Exception(
        pht(
          'Almanac service, device, property, network and namespace names '.
          'must begin and end with a letter or number.'));
    }

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Rewrite the offending junction: 'web-.east' -> 'web.east' or 'web-east'.
  2. After sanitizing, collapse invalid sequences: $name = preg_replace('/(\.-)|(-\.)/', '.', $name);
  3. Prefer a canonical slugify step (lowercase, replace non-alnum runs with a single '-') instead of piecemeal replacement.

Example fix

// before
$name = str_replace('/', '-', 'web./east'); // 'web.-east' -> throws

// after
$name = strtolower(preg_replace('/[^a-z0-9]+/i', '-', 'web./east')); // 'web-east'
$name = trim($name, '-.');
Defensive patterns

Strategy: validation

Validate before calling

if (preg_match('/\.-|-\./', $name)) {
  throw new Exception('Hyphens may not be adjacent to periods.');
}
// Canonical slugify avoids the pattern entirely:
$name = strtolower(preg_replace('/[^a-z0-9.-]+/', '-', $raw));

Type guard

function hasNoHyphenAdjacentToPeriod($name) {
  return !preg_match('/\.-|-\./', $name);
}

Try / catch

try {
  AlmanacNames::validateName($name);
} catch (Exception $ex) {
  if (preg_match('/hyphens adjacent to periods/', $ex->getMessage())) {
    $name = preg_replace('/\.-|-\./', '.', $name); // normalize, re-validate all rules
    AlmanacNames::validateName($name);
  } else {
    throw $ex;
  }
}

Prevention

When it happens

Trigger: Any submitted name containing '.-' or '-.', commonly produced when a template appends '-' to an empty segment and then joins with '.', or vice versa.

Common situations: Name builders that suffix each component with '-' before dot-joining; sanitizers that replace a bad char with '-' right next to an existing dot ('web/1' -> 'web.1' is fine, 'web./1' -> 'web.-1' is not).

Related errors


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