{"record":{"id":"48f0afe7fd6cce3a","repo":"phacility/phabricator","slug":"another-namespace-with-this-name-already-exists-e","errorCode":null,"errorMessage":"Another namespace with this name already exists. Each namespace must have a unique name.","messagePattern":"Another namespace with this name already exists\\. Each namespace must have a unique name\\.","errorType":"validation","errorClass":"PhabricatorApplicationTransactionValidationException","httpStatus":null,"severity":"error","filePath":"src/applications/almanac/editor/AlmanacNamespaceEditor.php","lineNumber":46,"sourceCode":"    return $types;\n  }\n\n  protected function didCatchDuplicateKeyException(\n    PhabricatorLiskDAO $object,\n    array $xactions,\n    Exception $ex) {\n\n    $errors = array();\n\n    $errors[] = new PhabricatorApplicationTransactionValidationError(\n      null,\n      pht('Invalid'),\n      pht(\n        'Another namespace with this name already exists. Each namespace '.\n        'must have a unique name.'),\n      null);\n\n    throw new PhabricatorApplicationTransactionValidationException($errors);\n  }\n\n}\n","sourceCodeStart":28,"sourceCodeEnd":50,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/almanac/editor/AlmanacNamespaceEditor.php#L28-L50","documentation":"Thrown by PhabricatorRepository::assertValidRepositorySlug() when a repository short name does not end with a letter or number. Trailing separators are rejected to avoid accidental double separators when the slug is joined into URIs or paths and to keep clone URLs clean. It is raised from the preg_match('/[a-zA-Z0-9]\\z/', $slug) check when the short-name transaction applies a value ending in '.', '-', or '_'.","triggerScenarios":"Setting a short name like 'utils-' or 'repo.': the end-anchor regex at PhabricatorRepository.php:403 finds no trailing letter/digit and throws.","commonSituations":"Sanitizer pipelines that replace invalid runs with hyphens but never trim the tail ('widget (dev)' -> 'widget-dev-'); names truncated mid-separator by length limits; copy-paste trailing punctuation.","solutions":["Trim trailing separators from the name: rtrim($slug, '._-').","Review generated slugs after character replacement and length truncation, since both can leave a dangling separator.","Pre-validate with PhabricatorRepository::isValidRepositorySlug()."],"exampleFix":"// before\n$slug = preg_replace('/[^a-zA-Z0-9._-]/', '-', 'widget (dev)'); // 'widget--dev-'\n\n// after\n$slug = rtrim(preg_replace('/[^a-zA-Z0-9._-]+/', '-', 'widget (dev)'), '._-'); // 'widget-dev'","handlingStrategy":"type-guard","validationCode":"$slug = rtrim($slug, '._-');","typeGuard":"function isValidShortName($slug) {\n  return PhabricatorRepository::isValidRepositorySlug((string)$slug);\n}","tryCatchPattern":"try {\n  PhabricatorRepository::assertValidRepositorySlug($slug);\n} catch (Exception $ex) {\n  // strip trailing separators and revalidate, or reject\n}","preventionTips":["Trim trailing '._-' after sanitization and after length truncation.","Add UI hints that short names must end with a letter or number."],"tags":["phabricator","php","validation","repository-shortname","naming-rules"],"backgroundTag":"invalid-identifier-suffix","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}