{"record":{"id":"a63813a52e3d2ee4","repo":"phacility/phabricator","slug":"repository-s-exists-on-more-than-one-device-bu","errorCode":null,"errorMessage":"Repository \"%s\" exists on more than one device, but no device has any repository version information. There is no way for the software to determine which copy of the existing data is authoritative. Promote a device or see \"Ambiguous Leaders\" in the documentation.","messagePattern":"Repository \"(.+?)\" exists on more than one device, but no device has any repository version information\\. There is no way for the software to determine which copy of the existing data is authoritative\\. Promote a device or see \"Ambiguous Leaders\" in the documentation\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php","lineNumber":273,"sourceCode":"      // might erase some or all of the data in the repository.\n\n      // Since this is dangerous, we refuse to guess unless there is only one\n      // device. If we're the only device in the group, we obviously must be\n      // a leader.\n\n      $service = $repository->loadAlmanacService();\n      if (!$service) {\n        throw new Exception(pht('Failed to load repository cluster service.'));\n      }\n\n      $bindings = $service->getActiveBindings();\n      $device_map = array();\n      foreach ($bindings as $binding) {\n        $device_map[$binding->getDevicePHID()] = true;\n      }\n\n      if (count($device_map) > 1) {\n        throw new Exception(\n          pht(\n            'Repository \"%s\" exists on more than one device, but no device '.\n            'has any repository version information. There is no way for the '.\n            'software to determine which copy of the existing data is '.\n            'authoritative. Promote a device or see \"Ambiguous Leaders\" in '.\n            'the documentation.',\n            $repository->getDisplayName()));\n      }\n\n      if (empty($device_map[$device->getPHID()])) {\n        throw new Exception(\n          pht(\n            'Repository \"%s\" is being synchronized on device \"%s\", but '.\n            'this device is not bound to the corresponding cluster '.\n            'service (\"%s\").',\n            $repository->getDisplayName(),\n            $device->getName(),\n            $service->getName()));","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php#L255-L291","documentation":"Leader-election safety check: the repository exists on more than one device, but the working-copy version table has no rows for any device, so there is no way to know which copy is authoritative. Picking wrong could erase some or all of the repository's data, so Phabricator refuses to guess and demands an explicit operator decision (see 'Ambiguous Leaders' in the Cluster: Repositories documentation).","triggerScenarios":"A repository that already has copies on two or more devices is clustered for the first time (or its version rows were lost), and any sync or push triggers leader election with zero version records.","commonSituations":"Growing a standalone install into a cluster by binding a second device that already happens to hold copies; restoring an old DB dump that predates the version table; manually truncating phabricator_repository_workingcopyversion.","solutions":["Back up every copy first, then temporarily remove all but one binding so exactly one device hosts the repository; let it sync and write version rows; re-add the other bindings so they fetch from the now-unambiguous leader","Alternatively promote the device whose data you know is authoritative, following 'Ambiguous Leaders' in the Cluster: Repositories documentation (version-table surgery / bin/repository tooling)","Before either step, compare the copies (heads, sizes, latest commits) so you do not destroy unique data on the losing device"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before binding a second device, assert version rows exist\n$versions = PhabricatorRepositoryWorkingCopyVersion::loadVersions($repository->getPHID());\n$binding_count = count($service->getActiveBindings());\nif (!$versions && $binding_count > 1) {\n  // refuse to scale out until exactly one device holds the repository\n}","typeGuard":"function hasUnambiguousLeader(array $devices, array $versions) {\n  return count($devices) <= 1 || count($versions) > 0;\n}","tryCatchPattern":"try {\n  $engine->synchronizeWorkingCopy();\n} catch (Exception $ex) {\n  // freeze automated writes, open an operator task citing 'Ambiguous Leaders'; never auto-retry\n}","preventionTips":["Cluster a repository only while it lives on exactly one device, then add bindings","Never hand-edit or truncate phabricator_repository_workingcopyversion","Back up all copies before resolving ambiguity manually"],"tags":["cluster","leader-election","data-safety","almanac","phabricator"],"backgroundTag":"cluster-split-brain","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}