phacility/phabricator · critical · Exception
This revision has no diffs. Something has gone quite wrong.
Error message
This revision has no diffs. Something has gone quite wrong.
What it means
A revision page requires at least one diff; the controller throws this invariant error when a DifferentialRevision row exists with zero attached diffs. Normal Phabricator flows always create revisions together with a first diff, so this error signals damaged or abnormal data.
Source
Thrown at src/applications/differential/controller/DifferentialRevisionViewController.php:67
$revision = id(new DifferentialRevisionQuery())
->withIDs(array($this->revisionID))
->setViewer($viewer)
->needReviewers(true)
->needReviewerAuthority(true)
->needCommitPHIDs(true)
->executeOne();
if (!$revision) {
return new Aphront404Response();
}
$diffs = id(new DifferentialDiffQuery())
->setViewer($viewer)
->withRevisionIDs(array($this->revisionID))
->execute();
$diffs = array_reverse($diffs, $preserve_keys = true);
if (!$diffs) {
throw new Exception(
pht('This revision has no diffs. Something has gone quite wrong.'));
}
$revision->attachActiveDiff(last($diffs));
$diff_vs = $this->getOldDiffID($revision, $diffs);
if ($diff_vs instanceof AphrontResponse) {
return $diff_vs;
}
$target_id = $this->getNewDiffID($revision, $diffs);
if ($target_id instanceof AphrontResponse) {
return $target_id;
}
$target = $diffs[$target_id];
$target_manual = $target;View on GitHub (pinned to 5720a38cfe)
Solutions
- Create revisions through the API or UI (differential.creatediff plus differential.updaterevision) so every revision gets at least one diff.
- Repair the data: attach a diff to the revision or remove the empty revision row.
- Restore from backups if the diffs were lost accidentally.
Defensive patterns
Strategy: try-catch
Try / catch
try {
// render or operate on the revision
} catch (Exception $ex) {
if (preg_match('/has no diffs/', $ex->getMessage())) {
// data integrity violation: quarantine the revision and alert the admin
} else {
throw $ex;
}
} Prevention
- Create revisions through the API or UI so they always receive a first diff.
- Never insert revision rows directly into the database.
- When removing diffs, remove their revisions in the same operation; back up first.
When it happens
Trigger: Opening a revision whose diffs were all deleted or never created: revisions inserted directly into the database, partial creation failures, or cleanup scripts that removed diffs without the revision.
Common situations: Rows created by migration or seeding scripts that bypass the API; broken imports; database-level deletion of diffs that left empty revisions behind.
Related errors
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/034dc4e01e46e546.
Report an issue: GitHub.