phacility/phabricator · error · ConduitException
ERR_BAD_REVISION
ERR_BAD_REVISION
Error message
ERR_BAD_REVISION
What it means
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)'.
Source
Thrown at src/applications/differential/conduit/DifferentialGetRevisionConduitAPIMethod.php:50
protected function defineErrorTypes() {
return array(
'ERR_BAD_REVISION' => pht('No such revision exists.'),
);
}
protected function execute(ConduitAPIRequest $request) {
$diff = null;
$revision_id = $request->getValue('revision_id');
$revision = id(new DifferentialRevisionQuery())
->withIDs(array($revision_id))
->setViewer($request->getUser())
->needReviewers(true)
->needCommitPHIDs(true)
->executeOne();
if (!$revision) {
throw new ConduitException('ERR_BAD_REVISION');
}
$reviewer_phids = $revision->getReviewerPHIDs();
$diffs = id(new DifferentialDiffQuery())
->setViewer($request->getUser())
->withRevisionIDs(array($revision_id))
->needChangesets(true)
->execute();
$diff_dicts = mpull($diffs, 'getDiffDict');
$commit_dicts = array();
$commit_phids = $revision->getCommitPHIDs();
$handles = id(new PhabricatorHandleQuery())
->setViewer($request->getUser())
->withPHIDs($commit_phids)
->execute();
View on GitHub (pinned to 5720a38cfe)
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.
Example fix
// before
$params = array('revision_id' => 'D123');
$client->callMethodSynchronous('differential.getrevision', $params);
// after
$params = array('revision_id' => 123);
$client->callMethodSynchronous('differential.getrevision', $params); Defensive patterns
Strategy: validation
Validate before calling
$response = $client->callMethodSynchronous('differential.revision.search', array(
'constraints' => array('ids' => array($revision_id)),
));
if (empty($response['data'])) {
throw new InvalidArgumentException(
'Revision '.$revision_id.' does not exist or is not visible.');
} Type guard
function isRevisionID($value) {
return is_int($value) && $value > 0;
} Try / catch
try {
$info = $client->callMethodSynchronous('differential.getrevision', $params);
} catch (ConduitClientException $ex) {
if ($ex->getErrorCode() === 'ERR_BAD_REVISION') {
// nonexistent or policy-hidden revision: skip or report 404-equivalent
} else {
throw $ex;
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- ERR_BAD_REVISION
- ERR_NOT_FOUND
- ERR_BAD_REVISION
- Unsupported action "%s".
- Field "changes" must be non-empty.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/0534553746365bf8.
Report an issue: GitHub.