phacility/phabricator · critical · Exception

Repository "%s" exists on more than one device, but no devic

Error message

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.

What it means

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).

Source

Thrown at src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php:273

      // might erase some or all of the data in the repository.

      // Since this is dangerous, we refuse to guess unless there is only one
      // device. If we're the only device in the group, we obviously must be
      // a leader.

      $service = $repository->loadAlmanacService();
      if (!$service) {
        throw new Exception(pht('Failed to load repository cluster service.'));
      }

      $bindings = $service->getActiveBindings();
      $device_map = array();
      foreach ($bindings as $binding) {
        $device_map[$binding->getDevicePHID()] = true;
      }

      if (count($device_map) > 1) {
        throw new Exception(
          pht(
            '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.',
            $repository->getDisplayName()));
      }

      if (empty($device_map[$device->getPHID()])) {
        throw new Exception(
          pht(
            'Repository "%s" is being synchronized on device "%s", but '.
            'this device is not bound to the corresponding cluster '.
            'service ("%s").',
            $repository->getDisplayName(),
            $device->getName(),
            $service->getName()));

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. 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
  2. Alternatively promote the device whose data you know is authoritative, following 'Ambiguous Leaders' in the Cluster: Repositories documentation (version-table surgery / bin/repository tooling)
  3. Before either step, compare the copies (heads, sizes, latest commits) so you do not destroy unique data on the losing device
Defensive patterns

Strategy: validation

Validate before calling

// before binding a second device, assert version rows exist
$versions = PhabricatorRepositoryWorkingCopyVersion::loadVersions($repository->getPHID());
$binding_count = count($service->getActiveBindings());
if (!$versions && $binding_count > 1) {
  // refuse to scale out until exactly one device holds the repository
}

Type guard

function hasUnambiguousLeader(array $devices, array $versions) {
  return count($devices) <= 1 || count($versions) > 0;
}

Try / catch

try {
  $engine->synchronizeWorkingCopy();
} catch (Exception $ex) {
  // freeze automated writes, open an operator task citing 'Ambiguous Leaders'; never auto-retry
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/a63813a52e3d2ee4. Report an issue: GitHub.