{"record":{"id":"8e312d4655e920fe","repo":"phacility/phabricator","slug":"diff-s-has-wrong-revision-id-s-expected","errorCode":null,"errorMessage":"Diff (\"%s\") has wrong revision ID (\"%s\", expected \"%s\").","messagePattern":"Diff \\(\"(.+?)\"\\) has wrong revision ID \\(\"(.+?)\", expected \"(.+?)\"\\)\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/drydock/operation/DrydockLandRepositoryOperation.php","lineNumber":214,"sourceCode":"    $revision = $operation->getObject();\n\n    $diff_phid = $operation->getProperty('differential.diffPHID');\n\n    $diff = id(new DifferentialDiffQuery())\n      ->setViewer($viewer)\n      ->withPHIDs(array($diff_phid))\n      ->executeOne();\n    if (!$diff) {\n      throw new Exception(\n        pht(\n          'Unable to load diff \"%s\".',\n          $diff_phid));\n    }\n\n    $diff_revid = $diff->getRevisionID();\n    $revision_id = $revision->getID();\n    if ($diff_revid != $revision_id) {\n      throw new Exception(\n        pht(\n          'Diff (\"%s\") has wrong revision ID (\"%s\", expected \"%s\").',\n          $diff_phid,\n          $diff_revid,\n          $revision_id));\n    }\n\n    return $diff;\n  }\n\n  public function getBarrierToLanding(\n    PhabricatorUser $viewer,\n    DifferentialRevision $revision) {\n\n    $repository = $revision->getRepository();\n    if (!$repository) {\n      return array(\n        'title' => pht('No Repository'),","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/drydock/operation/DrydockLandRepositoryOperation.php#L196-L232","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\n$diff = id(new DifferentialDiffQuery())\n  ->setViewer($viewer)\n  ->withPHIDs(array($stale_diff_phid))\n  ->executeOne();\n// Exception: Diff (\"PHID-DIFF-x\") has wrong revision ID (\"101\", expected \"102\").\n\n// after\n$diff_phid = $revision->getActiveDiff()->getPHID(); // captured from the bound revision\n$diff = id(new DifferentialDiffQuery())\n  ->setViewer($viewer)\n  ->withPHIDs(array($diff_phid))\n  ->executeOne();","handlingStrategy":"validation","validationCode":"// Check diff/revision pairing before land executes:\n$diff = id(new DifferentialDiffQuery())\n  ->setViewer($viewer)\n  ->withPHIDs(array($operation->getProperty('differential.diffPHID')))\n  ->executeOne();\n$revision = $operation->getObject();\nif ($diff->getRevisionID() != $revision->getID()) {\n  // stale pairing: rebuild the operation from the revision's active diff\n}","typeGuard":null,"tryCatchPattern":"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 }","preventionTips":["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"],"tags":["drydock","phabricator","land-operation","differential","data-integrity","stale-state"],"backgroundTag":"entity-relationship-mismatch","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}