phacility/phabricator · error · Exception
Diff ("%s") has wrong revision ID ("%s", expected "%s").
Error message
Diff ("%s") has wrong revision ID ("%s", expected "%s"). What it means
After loading the diff, the land operation verifies the diff actually belongs to the revision on the operation by comparing `$diff->getRevisionID()` with the revision's ID. A mismatch means the stored `differential.diffPHID` points at a diff attached to a different revision — merging would land someone else's changes under this revision's commit message. This is a data-integrity guard, so it throws rather than guessing.
Source
Thrown at src/applications/drydock/operation/DrydockLandRepositoryOperation.php:214
$revision = $operation->getObject();
$diff_phid = $operation->getProperty('differential.diffPHID');
$diff = id(new DifferentialDiffQuery())
->setViewer($viewer)
->withPHIDs(array($diff_phid))
->executeOne();
if (!$diff) {
throw new Exception(
pht(
'Unable to load diff "%s".',
$diff_phid));
}
$diff_revid = $diff->getRevisionID();
$revision_id = $revision->getID();
if ($diff_revid != $revision_id) {
throw new Exception(
pht(
'Diff ("%s") has wrong revision ID ("%s", expected "%s").',
$diff_phid,
$diff_revid,
$revision_id));
}
return $diff;
}
public function getBarrierToLanding(
PhabricatorUser $viewer,
DifferentialRevision $revision) {
$repository = $revision->getRepository();
if (!$repository) {
return array(
'title' => pht('No Repository'),View on GitHub (pinned to 5720a38cfe)
Solutions
- Discard the stale operation (release it) and issue a fresh land request so diff PHID and revision are captured atomically
- Verify the pairing manually: load the diff and check its revisionID matches the operation's object
- If you maintain custom creation code, read the diff PHID from the same revision object you bind to the operation, at the same moment
- Do not hand-edit differential.diffPHID on existing operations
Example fix
// before
$diff = id(new DifferentialDiffQuery())
->setViewer($viewer)
->withPHIDs(array($stale_diff_phid))
->executeOne();
// Exception: Diff ("PHID-DIFF-x") has wrong revision ID ("101", expected "102").
// after
$diff_phid = $revision->getActiveDiff()->getPHID(); // captured from the bound revision
$diff = id(new DifferentialDiffQuery())
->setViewer($viewer)
->withPHIDs(array($diff_phid))
->executeOne(); Defensive patterns
Strategy: validation
Validate before calling
// Check diff/revision pairing before land executes:
$diff = id(new DifferentialDiffQuery())
->setViewer($viewer)
->withPHIDs(array($operation->getProperty('differential.diffPHID')))
->executeOne();
$revision = $operation->getObject();
if ($diff->getRevisionID() != $revision->getID()) {
// stale pairing: rebuild the operation from the revision's active diff
} Try / catch
catch (Exception $ex) { on 'has wrong revision ID', discard the stale operation (release it) rather than retrying; re-issue land so diff and revision are captured together } Prevention
- Capture diff PHID and revision binding atomically at land-request time
- Never hand-edit differential.diffPHID on queued operations
- Treat revision updates during a queued land as invalidating that operation
When it happens
Trigger: The revision is updated while a land operation is queued, and stale properties mix the new revision with an old diff; manual property edits pointing diffPHID at another revision's diff; code that copies operations/properties between revisions (e.g. revision-forking tooling).
Common situations: Race between 'Request Changes'/'Land' and the author updating the revision; diffs re-parented by database repair; multiple land attempts reusing an older operation row.
Related errors
- Invalid or unknown object ("%s") for land operation, expecte
- Unable to load diff "%s".
- Unable to load changeset.
- Unable to load diff.
- Unable to load revision.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/8e312d4655e920fe.
Report an issue: GitHub.