phacility/phabricator · error · PhutilAggregateException
Exceptions occurred while mirroring the "%s" repository.
Error message
Exceptions occurred while mirroring the "%s" repository.
What it means
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.
Source
Thrown at src/applications/repository/engine/PhabricatorRepositoryMirrorEngine.php:49
foreach ($uris as $mirror) {
if ($mirror->getIsDisabled()) {
continue;
}
$io_type = $mirror->getEffectiveIOType();
if ($io_type != $io_mirror) {
continue;
}
try {
$this->pushRepositoryToMirror($repository, $mirror);
} catch (Exception $ex) {
$exceptions[] = $ex;
}
}
if ($exceptions) {
throw new PhutilAggregateException(
pht(
'Exceptions occurred while mirroring the "%s" repository.',
$repository->getDisplayName()),
$exceptions);
}
}
private function pushRepositoryToMirror(
PhabricatorRepository $repository,
PhabricatorRepositoryURI $mirror_uri) {
$this->log(
pht(
'Pushing to remote "%s"...',
$mirror_uri->getEffectiveURI()));
if ($repository->isGit()) {
$this->pushToGitRepository($repository, $mirror_uri);View on GitHub (pinned to 5720a38cfe)
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
Defensive patterns
Strategy: try-catch
Validate before calling
// Before the mirror cycle, smoke-test each mirror URI from the daemon host: // git ls-remote <mirror_uri> (expect exit code 0) // A failure here predicts the aggregate exception later.
Try / catch
try {
id(new PhabricatorRepositoryMirrorEngine())
->setRepository($repository)
->pushToMirrors();
} catch (PhutilAggregateException $ex) {
foreach ($ex->getAggregateExceptions() as $mirror_ex) {
phlog('Mirror failure: '.$mirror_ex->getMessage()); // fix these individually
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- This repository is read-only over SSH (tried to execute prot
- No repository "%s" exists!
- Another process is currently discovering repository "%s", sk
- Another process is currently updating repository "%s", skipp
- Specify one or more repositories to push to mirrors.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/52f8bcdf7a64c485.
Report an issue: GitHub.