{"record":{"id":"0534553746365bf8","repo":"phacility/phabricator","slug":"err-bad-revision-053455","errorCode":"ERR_BAD_REVISION","errorMessage":"ERR_BAD_REVISION","messagePattern":"ERR_BAD_REVISION","errorType":"error_code","errorClass":"ConduitException","httpStatus":null,"severity":"error","filePath":"src/applications/differential/conduit/DifferentialGetRevisionConduitAPIMethod.php","lineNumber":50,"sourceCode":"  protected function defineErrorTypes() {\n    return array(\n      'ERR_BAD_REVISION' => pht('No such revision exists.'),\n    );\n  }\n\n  protected function execute(ConduitAPIRequest $request) {\n    $diff = null;\n\n    $revision_id = $request->getValue('revision_id');\n    $revision = id(new DifferentialRevisionQuery())\n      ->withIDs(array($revision_id))\n      ->setViewer($request->getUser())\n      ->needReviewers(true)\n      ->needCommitPHIDs(true)\n      ->executeOne();\n\n    if (!$revision) {\n      throw new ConduitException('ERR_BAD_REVISION');\n    }\n\n    $reviewer_phids = $revision->getReviewerPHIDs();\n\n    $diffs = id(new DifferentialDiffQuery())\n      ->setViewer($request->getUser())\n      ->withRevisionIDs(array($revision_id))\n      ->needChangesets(true)\n      ->execute();\n    $diff_dicts = mpull($diffs, 'getDiffDict');\n\n    $commit_dicts = array();\n    $commit_phids = $revision->getCommitPHIDs();\n    $handles = id(new PhabricatorHandleQuery())\n      ->setViewer($request->getUser())\n      ->withPHIDs($commit_phids)\n      ->execute();\n","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/differential/conduit/DifferentialGetRevisionConduitAPIMethod.php#L32-L68","documentation":"Thrown by the Conduit method differential.getrevision when the revision_id parameter does not resolve to a DifferentialRevision that the requesting user may see. The underlying query is policy-filtered, so a nonexistent ID and a policy-hidden revision produce the same error. It is the legacy read API's way of saying 'no such revision (that you can access)'.","triggerScenarios":"Calling differential.getrevision with a nonexistent revision_id; passing the monogram string 'D123' instead of the integer 123; passing 0 or a negative number; using a token whose user cannot see the revision because of its view policy or a governing project policy.","commonSituations":"Scripts that extract 'D123' from a commit message and forward it verbatim; migration or reporting jobs that run after revisions were deleted; bot accounts that are not members of the project that governs the revision; clients pointed at the wrong Phabricator instance where the ID does not exist.","solutions":["Pass the numeric ID without the 'D' prefix: send 123, not 'D123'.","Pre-check with differential.revision.search using constraints {\"ids\":[123]}; an empty result means the ID is wrong or invisible to this user.","Verify the conduit user can see the revision (object view policy, project membership).","Confirm you are talking to the instance the revision lives on."],"exampleFix":"// before\n$params = array('revision_id' => 'D123');\n$client->callMethodSynchronous('differential.getrevision', $params);\n\n// after\n$params = array('revision_id' => 123);\n$client->callMethodSynchronous('differential.getrevision', $params);","handlingStrategy":"validation","validationCode":"$response = $client->callMethodSynchronous('differential.revision.search', array(\n  'constraints' => array('ids' => array($revision_id)),\n));\nif (empty($response['data'])) {\n  throw new InvalidArgumentException(\n    'Revision '.$revision_id.' does not exist or is not visible.');\n}","typeGuard":"function isRevisionID($value) {\n  return is_int($value) && $value > 0;\n}","tryCatchPattern":"try {\n  $info = $client->callMethodSynchronous('differential.getrevision', $params);\n} catch (ConduitClientException $ex) {\n  if ($ex->getErrorCode() === 'ERR_BAD_REVISION') {\n    // nonexistent or policy-hidden revision: skip or report 404-equivalent\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Strip the 'D' prefix and cast to int before sending revision_id.","Pre-validate IDs with differential.revision.search.","Run conduit jobs under an account whose policies cover the target objects."],"tags":["phabricator","conduit","differential","revision-not-found"],"backgroundTag":"resource-not-found","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}