{"record":{"id":"519f47ae144610fb","repo":"phacility/phabricator","slug":"the-chosen-callsign-or-repository-short-name-is-al","errorCode":null,"errorMessage":"The chosen callsign or repository short name is already in use by another repository.","messagePattern":"The chosen callsign or repository short name is already in use by another repository\\.","errorType":"validation","errorClass":"PhabricatorApplicationTransactionValidationException","httpStatus":null,"severity":"error","filePath":"src/applications/repository/editor/PhabricatorRepositoryEditor.php","lineNumber":39,"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        'The chosen callsign or repository short name is already in '.\n        'use by another repository.'),\n      null);\n\n    throw new PhabricatorApplicationTransactionValidationException($errors);\n  }\n\n  protected function supportsSearch() {\n    return true;\n  }\n\n  protected function applyFinalEffects(\n    PhabricatorLiskDAO $object,\n    array $xactions) {\n\n    // If the repository does not have a local path yet, assign it one based\n    // on its ID. We can't do this earlier because we won't have an ID yet.\n    $local_path = $object->getLocalPath();\n    if ($local_path === null || !strlen($local_path)) {\n      $local_key = 'repository.default-local-path';\n\n      $local_root = PhabricatorEnv::getEnvConfig($local_key);\n      $local_root = rtrim($local_root, '/');","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/repository/editor/PhabricatorRepositoryEditor.php#L21-L57","documentation":"Thrown by PhabricatorRepositoryEditor::didCatchDuplicateKeyException() when saving or editing a repository triggers a database duplicate-key exception on a unique index. In Phabricator, both the repository callsign (e.g. ABC) and the repository short name (e.g. myrepo used in diffusion URLs) are globally unique. The raw Lisk duplicate-key error is converted into a PhabricatorApplicationTransactionValidationException so the UI can show a field-level validation message.","triggerScenarios":"Creating or editing a repository via Diffusion UI, Conduit (repository.create / repository.edit), or CLI where the chosen callsign or short name collides with an existing repository row; the catch wraps the INSERT/UPDATE inside applyTransactions. Also triggered by re-importing a repository that already exists under another name, or by two concurrent creates picking the same callsign.","commonSituations":"Creating a repo with a callsign already used by another (possibly dormant) repository; renaming a repo to a short name another repo occupies; migration or import scripts that assume the target name is free; case-sensitivity surprises such as Repo vs repo depending on DB collation.","solutions":["Pick a different callsign or short name for the repository","Find the conflicting repository: browse /diffusion/ or query diffusion.repository.search via Conduit, then rename or delete it if it is an accidental duplicate","If writing a migration script, check for an existing repository by callsign and short name before creating","Retry the create or edit after the collision is resolved"],"exampleFix":"// before\nid(new PhabricatorRepository())\n  ->setCallsign('ABC')\n  ->setName('widgets')\n  ->save(); // throws: 'ABC' already in use\n\n// after\n$existing = id(new PhabricatorRepositoryQuery())\n  ->setViewer($viewer)\n  ->withCallsigns(array('ABC'))\n  ->executeOne();\nif ($existing) {\n  $repository = $existing; // reuse instead of colliding\n} else {\n  $repository = id(new PhabricatorRepository())\n    ->setCallsign('ABC')\n    ->setName('widgets')\n    ->save();\n}","handlingStrategy":"validation","validationCode":"// Before create/edit, check uniqueness the way the editor does:\n$existing = id(new PhabricatorRepositoryQuery())\n  ->setViewer($viewer)\n  ->withCallsigns(array($callsign))\n  ->executeOne();\nif ($existing) {\n  // pick another callsign or reuse this repository\n}","typeGuard":null,"tryCatchPattern":"try {\n  id(new PhabricatorRepositoryEditor())\n    ->setActor($viewer)\n    ->setContentSource($source)\n    ->applyTransactions($repository, $xactions);\n} catch (PhabricatorApplicationTransactionValidationException $ex) {\n  foreach ($ex->getErrors() as $error) {\n    // map the 'Invalid' message back to the callsign / short-name fields\n  }\n}","preventionTips":["Query for an existing callsign and short name before scripted repository creation","Reserve a callsign naming convention per team to avoid collisions","Treat the validation error as a field error on the callsign or short-name inputs in UI flows"],"tags":["phabricator","repository","duplicate-key","callsign","validation"],"backgroundTag":"unique-constraint-violation","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}