{"record":{"id":"aa72131832967af3","repo":"phacility/phabricator","slug":"almanac-service-device-property-network-and-nam-aa7213","errorCode":null,"errorMessage":"Almanac service, device, property, network and namespace names may not contain multiple consecutive periods.","messagePattern":"Almanac service, device, property, network and namespace names may not contain multiple consecutive periods\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/almanac/util/AlmanacNames.php","lineNumber":36,"sourceCode":"    }\n\n    if (!preg_match('/^[a-z0-9.-]+\\z/', $name)) {\n      throw new Exception(\n        pht(\n          'Almanac service, device, property, network and namespace names '.\n          'may only contain lowercase letters, numbers, hyphens, and '.\n          'periods.'));\n    }\n\n    if (preg_match('/(^|\\\\.)\\d+(\\z|\\\\.)/', $name)) {\n      throw new Exception(\n        pht(\n          'Almanac service, device, network, property and namespace names '.\n          'may not have any segments containing only digits.'));\n    }\n\n    if (preg_match('/\\.\\./', $name)) {\n      throw new Exception(\n        pht(\n          'Almanac service, device, property, network and namespace names '.\n          'may not contain multiple consecutive periods.'));\n    }\n\n    if (preg_match('/\\\\.-|-\\\\./', $name)) {\n      throw new Exception(\n        pht(\n          'Almanac service, device, property, network and namespace names '.\n          'may not contain hyphens adjacent to periods.'));\n    }\n\n    if (preg_match('/--/', $name)) {\n      throw new Exception(\n        pht(\n          'Almanac service, device, property, network and namespace names '.\n          'may not contain multiple consecutive hyphens.'));\n    }","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/almanac/util/AlmanacNames.php#L18-L54","documentation":"Fifth rule of AlmanacNames::validateName(): the name may not contain '..' (multiple consecutive periods). Empty segments between dots would produce ambiguous, non-DNS-safe identifiers, so they are rejected outright.","triggerScenarios":"Submitting names like 'db..east' or 'a...b', usually the result of string concatenation where one component was empty.","commonSituations":"Templates joining $env.$region.$role with an unset variable producing an empty segment; hand-typed names with double dots; pasting names with ellipsis characters normalized to dots.","solutions":["Ensure every joined component is non-empty before concatenation, or collapse empties: $name = implode('.', array_filter($parts));","Manually fix the double dot: 'db..east' -> 'db.east'.","Add a pre-check preg_match('/\\.\\./', $name) in your tooling with a clear error naming the offending input."],"exampleFix":"// before\n$name = implode('.', array($team, $env, $role)); // $env empty -> 'team..role'\n\n// after\n$name = implode('.', array_filter(array($team, $env, $role))); // skips empty parts","handlingStrategy":"validation","validationCode":"if (preg_match('/\\.\\./', $name)) {\n  throw new Exception('Name contains consecutive periods.');\n}\n// Safer construction: skip empty parts when joining.\n$name = implode('.', array_filter($parts, 'strlen'));","typeGuard":"function hasNoConsecutivePeriods($name) {\n  return strpos($name, '..') === false;\n}","tryCatchPattern":"try {\n  AlmanacNames::validateName($name);\n} catch (Exception $ex) {\n  if (preg_match('/multiple consecutive periods/', $ex->getMessage())) {\n    $name = str_replace('..', '.', $name); // collapse, then re-run all rules\n    AlmanacNames::validateName($name);\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Never implode over possibly-empty components without filtering them first.","Validate joined names with a quick strpos($name, '..') check in tooling.","Treat empty template variables as build errors, not as skipped segments."],"tags":["almanac","validation","naming","phabricator"],"backgroundTag":"identifier-validation-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}