{"record":{"id":"3890435b11fb46c5","repo":"phacility/phabricator","slug":"almanac-service-device-property-network-and-nam-389043","errorCode":null,"errorMessage":"Almanac service, device, property, network and namespace names may not contain multiple consecutive hyphens.","messagePattern":"Almanac service, device, property, network and namespace names may not contain multiple consecutive hyphens\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/almanac/util/AlmanacNames.php","lineNumber":50,"sourceCode":"          '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    }\n\n    if (!preg_match('/^[a-z0-9].*[a-z0-9]\\z/', $name)) {\n      throw new Exception(\n        pht(\n          'Almanac service, device, property, network and namespace names '.\n          'must begin and end with a letter or number.'));\n    }\n  }\n\n}\n","sourceCodeStart":32,"sourceCodeEnd":65,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/almanac/util/AlmanacNames.php#L32-L65","documentation":"Seventh rule of AlmanacNames::validateName(): the name may not contain '--' (multiple consecutive hyphens). DNS labels disallow consecutive hyphens except in special xn-- forms, and Phabricator rejects them uniformly for all Almanac object names.","triggerScenarios":"Submitting names like 'web--01' or 'a--b', most often after a sanitizer replaces a run of bad characters with hyphens (e.g. 'web__01' or 'web / 01' becoming 'web--01').","commonSituations":"Naive slugification replacing each invalid character individually; joining components with '-' where one side already ends in '-'.","solutions":["Collapse runs when sanitizing: $name = preg_replace('/-+/', '-', $name);","Fix the literal name: 'web--01' -> 'web-01'.","Use a single regex replacement of '/[^a-z0-9.-]+/' so whole runs become one hyphen, not several."],"exampleFix":"// before\n$name = preg_replace('/[^a-z0-9.-]/', '-', 'web__01'); // 'web--01' -> throws\n\n// after\n$name = preg_replace('/[^a-z0-9.-]+/', '-', 'web__01'); // 'web-01'","handlingStrategy":"validation","validationCode":"if (preg_match('/--/', $name)) {\n  throw new Exception('Name contains consecutive hyphens.');\n}\n// Prevent at construction time:\n$name = preg_replace('/-+/', '-', $name);","typeGuard":"function hasNoConsecutiveHyphens($name) {\n  return strpos($name, '--') === false;\n}","tryCatchPattern":"try {\n  AlmanacNames::validateName($name);\n} catch (Exception $ex) {\n  if (preg_match('/multiple consecutive hyphens/', $ex->getMessage())) {\n    $name = preg_replace('/-+/', '-', $name); // collapse, re-run all rules\n    AlmanacNames::validateName($name);\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Use '+-' quantifiers in slug regexes so runs collapse to a single hyphen.","Do not join strings with '-' when either side may already end with '-'.","Round-trip generated names through AlmanacNames::validateName() in tests."],"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"}