{"record":{"id":"52f8bcdf7a64c485","repo":"phacility/phabricator","slug":"exceptions-occurred-while-mirroring-the-s-repos","errorCode":null,"errorMessage":"Exceptions occurred while mirroring the \"%s\" repository.","messagePattern":"Exceptions occurred while mirroring the \"(.+?)\" repository\\.","errorType":"exception","errorClass":"PhutilAggregateException","httpStatus":null,"severity":"error","filePath":"src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php","lineNumber":49,"sourceCode":"    foreach ($uris as $mirror) {\n      if ($mirror->getIsDisabled()) {\n        continue;\n      }\n\n      $io_type = $mirror->getEffectiveIOType();\n      if ($io_type != $io_mirror) {\n        continue;\n      }\n\n      try {\n        $this->pushRepositoryToMirror($repository, $mirror);\n      } catch (Exception $ex) {\n        $exceptions[] = $ex;\n      }\n    }\n\n    if ($exceptions) {\n      throw new PhutilAggregateException(\n        pht(\n          'Exceptions occurred while mirroring the \"%s\" repository.',\n          $repository->getDisplayName()),\n        $exceptions);\n    }\n  }\n\n  private function pushRepositoryToMirror(\n    PhabricatorRepository $repository,\n    PhabricatorRepositoryURI $mirror_uri) {\n\n    $this->log(\n      pht(\n        'Pushing to remote \"%s\"...',\n        $mirror_uri->getEffectiveURI()));\n\n    if ($repository->isGit()) {\n      $this->pushToGitRepository($repository, $mirror_uri);","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php#L31-L67","documentation":"Thrown by PhabricatorRepositoryMirrorEngine after attempting to push a repository to every configured mirror when one or more pushes threw. The individual exceptions are collected and re-raised wrapped in a PhutilAggregateException naming the repository; inspect the aggregated exceptions to see each mirror's real failure such as auth, DNS, or non-fast-forward. Mirroring is best-effort per mirror, but any failure surfaces as this aggregate error in the task or daemon log.","triggerScenarios":"A mirror URI with wrong or expired credentials; mirror host unreachable due to firewall or DNS; SSH host key not yet trusted; git push rejected as non-fast-forward after the mirror diverged; mirror URI misconfigured as a normal read/write remote instead of a mirror.","commonSituations":"Credentials rotated on the mirror server but not updated in the repository URI config; mirror VM down for maintenance while the mirror daemon runs; first push to a new mirror before its host key was accepted; mirrors that received manual pushes and diverged.","solutions":["Read the wrapped exceptions inside the aggregate (daemon log or task detail); the actual fix is always in the per-mirror error","Test each mirror URI by hand as the daemon user with the exact git or ssh URL to reproduce the real failure","If SSH host key is the issue, connect once manually to accept it or add it to the daemon known_hosts","If a mirror diverged (non-fast-forward), align it by re-cloning from Phabricator or force-updating the mirror, then let the next mirror cycle run","Confirm each mirror URI has the correct mirror I/O type on the repository URIs screen"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before the mirror cycle, smoke-test each mirror URI from the daemon host:\n//   git ls-remote <mirror_uri>   (expect exit code 0)\n// A failure here predicts the aggregate exception later.","typeGuard":null,"tryCatchPattern":"try {\n  id(new PhabricatorRepositoryMirrorEngine())\n    ->setRepository($repository)\n    ->pushToMirrors();\n} catch (PhutilAggregateException $ex) {\n  foreach ($ex->getAggregateExceptions() as $mirror_ex) {\n    phlog('Mirror failure: '.$mirror_ex->getMessage()); // fix these individually\n  }\n}","preventionTips":["Keep mirror credentials current and monitor them like production secrets","Accept mirror host keys as the daemon user during initial setup","Alert on repeated mirror task failures instead of ignoring aggregate noise","Keep mirrors read-only targets so they cannot diverge"],"tags":["phabricator","mirroring","git-push","daemon","aggregated-errors"],"backgroundTag":"mirror-push-failed","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}