{"record":{"id":"baeba226e27ccbab","repo":"phacility/phabricator","slug":"almanac-service-device-property-network-and-nam-baeba2","errorCode":null,"errorMessage":"Almanac service, device, property, network and namespace names may only contain lowercase letters, numbers, hyphens, and periods.","messagePattern":"Almanac service, device, property, network and namespace names may only contain lowercase letters, numbers, hyphens, and periods\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/almanac/util/AlmanacNames.php","lineNumber":21,"sourceCode":"final class AlmanacNames extends Phobject {\n\n  public static function validateName($name) {\n    if (strlen($name) < 3) {\n      throw new Exception(\n        pht(\n          'Almanac service, device, property, network and namespace names '.\n          'must be at least 3 characters long.'));\n    }\n\n    if (strlen($name) > 100) {\n      throw new Exception(\n        pht(\n          'Almanac service, device, property, network and namespace names '.\n          'may not be more than 100 characters long.'));\n    }\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.'));","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/almanac/util/AlmanacNames.php#L3-L39","documentation":"Third rule of AlmanacNames::validateName(): the entire name must match /^[a-z0-9.-]+\\z/. Uppercase letters, underscores, spaces, slashes and every other character are rejected so names stay valid across DNS, URLs and shell contexts.","triggerScenarios":"Submitting a name containing uppercase letters ('Web-01'), underscores ('web_01'), spaces, or any non [a-z0-9.-] character such as colons or unicode.","commonSituations":"Copy-pasting hostnames containing underscores from inventory; teams used to AWS-style names with capital letters; trailing whitespace or newline sneaking in from form input.","solutions":["Use only lowercase letters, digits, hyphens and periods: 'web-01' not 'Web_01'.","Normalize programmatically: $name = strtolower($name); $name = preg_replace('/[^a-z0-9.-]+/', '-', $name); before submission.","Trim input first; trailing whitespace/newlines fail this regex too."],"exampleFix":"// before\n$device->setName('Web_Node #1'); // throws: invalid characters\n\n// after\n$name = strtolower('Web_Node #1');\n$name = preg_replace('/[^a-z0-9.-]+/', '-', $name);\n$device->setName('web-node-1');","handlingStrategy":"validation","validationCode":"if (!preg_match('/^[a-z0-9.-]+\\z/', $name)) {\n  throw new Exception('Name may only contain lowercase letters, digits, hyphens and periods.');\n}","typeGuard":"function hasValidAlmanacNameCharset($name) {\n  return (bool)preg_match('/^[a-z0-9.-]+\\z/', $name);\n}","tryCatchPattern":"try {\n  AlmanacNames::validateName($name);\n} catch (Exception $ex) {\n  if (preg_match('/may only contain lowercase/', $ex->getMessage())) {\n    $name = preg_replace('/[^a-z0-9.-]+/', '-', strtolower($name));\n    AlmanacNames::validateName($name); // re-run full rule set\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Lowercase and slugify all operator input before creating Almanac objects.","Ban underscores in host/service naming conventions from day one.","Trim whitespace and strip newlines from pasted names."],"tags":["almanac","validation","naming","charset","phabricator"],"backgroundTag":"identifier-validation-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}