{"record":{"id":"e649e555fbd9e320","repo":"phacility/phabricator","slug":"repository-s-is-being-synchronized-on-device","errorCode":null,"errorMessage":"Repository \"%s\" is being synchronized on device \"%s\", but this device is not bound to the corresponding cluster service (\"%s\").","messagePattern":"Repository \"(.+?)\" is being synchronized on device \"(.+?)\", but this device is not bound to the corresponding cluster service \\(\"(.+?)\"\\)\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php","lineNumber":284,"sourceCode":"      $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()));\n      }\n\n      // The current device is the only device in service, so it must be a\n      // leader. We can safely have any future nodes which come online read\n      // from it.\n      PhabricatorRepositoryWorkingCopyVersion::updateVersion(\n        $repository_phid,\n        $device_phid,\n        0);\n\n      $result_version = 0;","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php#L266-L302","documentation":"Leader election concluded this device must be the leader (single remaining device), but the active bindings of the repository's Almanac service do not include this device. In other words, this host is synchronizing a repository for a cluster service it no longer belongs to, which indicates a configuration drift the engine refuses to paper over.","triggerScenarios":"A device was removed (or its binding disabled) from the repository's Almanac service while its daemons still had pending sync/discovery jobs for that repository; or working-copy storage ended up on a host that was never bound to the service.","commonSituations":"Removing a device from a service during maintenance without draining its job queue; hand-copying repository storage to a new host and expecting it to synchronize without binding it.","solutions":["Re-add an active binding for this device to the repository's Almanac service, with the correct protocol setting","Or stop the daemons on this device / move those repository jobs to properly bound devices, and let cluster state settle","After rebinding, run 'bin/repository update <monogram>' on this device to resynchronize"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"$device = AlmanacKeys::getLiveDevice();\n$bound = mpull($service->getActiveBindings(), 'getDevicePHID');\nif (!in_array($device->getPHID(), $bound, true)) {\n  // this host must not run sync jobs for the service; skip or alert\n}","typeGuard":"function isDeviceBoundToService($device_phid, array $bindings) {\n  return in_array($device_phid, mpull($bindings, 'getDevicePHID'), true);\n}","tryCatchPattern":"try {\n  $engine->synchronizeWorkingCopy();\n} catch (Exception $ex) {\n  // stop dispatching this repository's jobs on this host until the binding is restored\n}","preventionTips":["Drain a device's repository job queue before removing its binding from the service","Monitor for orphaned working copies: local repos whose device is no longer bound"],"tags":["cluster","almanac","binding","device-mismatch","phabricator"],"backgroundTag":"service-binding-mismatch","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}