phacility/phabricator · error · ConduitException
ERR-BAD-REVISION
ERR-BAD-REVISION
Error message
ERR-BAD-REVISION
What it means
Thrown by the differential.createinline Conduit method. When revisionID is provided, the method loads the revision with a policy-filtered DifferentialRevisionQuery; if no visible revision matches, it throws ConduitException('ERR-BAD-REVISION'). This happens before any diff resolution or inline-comment creation.
Source
Thrown at src/applications/differential/conduit/DifferentialCreateInlineConduitAPIMethod.php:57
'A file path was not provided.'),
'ERR-BAD-FILE' => pht(
"Requested file doesn't exist in this revision."),
);
}
protected function execute(ConduitAPIRequest $request) {
$rid = $request->getValue('revisionID');
$did = $request->getValue('diffID');
if ($rid) {
// Given both a revision and a diff, check that they match.
// Given only a revision, find the active diff.
$revision = id(new DifferentialRevisionQuery())
->setViewer($request->getUser())
->withIDs(array($rid))
->executeOne();
if (!$revision) {
throw new ConduitException('ERR-BAD-REVISION');
}
if (!$did) { // did not!
$diff = $revision->loadActiveDiff();
$did = $diff->getID();
} else { // did too!
$diff = id(new DifferentialDiff())->load($did);
if (!$diff || $diff->getRevisionID() != $rid) {
throw new ConduitException('ERR-BAD-DIFF');
}
}
} else if ($did) {
// Given only a diff, find the parent revision.
$diff = id(new DifferentialDiff())->load($did);
if (!$diff) {
throw new ConduitException('ERR-BAD-DIFF');
}
$rid = $diff->getRevisionID();View on GitHub (pinned to 5720a38cfe)
Solutions
- Send revisionID as the bare integer and verify it first with differential.query
- Ensure the conduit token's user can see the revision
- Alternatively omit revisionID and pass only diffID - the server resolves the revision from the diff
- Catch ERR-BAD-REVISION in batch comment jobs and continue with remaining items
Example fix
// before $params = array( 'revisionID' => 'D789', 'filePath' => 'src/app.php', 'content' => 'Wrong order.', ); // after $params = array( 'revisionID' => 789, 'filePath' => 'src/app.php', 'content' => 'Wrong order.', );
Defensive patterns
Strategy: try-catch
Validate before calling
$found = $client->callMethodSynchronous(
'differential.query',
array('ids' => array((int)$rid)));
if (!$found) {
return; // cannot attach inline to unknown revision
} Try / catch
try {
$client->callMethodSynchronous('differential.createinline', $params);
} catch (ConduitClientException $ex) {
if ($ex->getErrorCode() === 'ERR-BAD-REVISION') {
// revisionID wrong or invisible: log and skip
} else {
throw $ex;
}
} Prevention
- Cast revisionID to int and pre-check with differential.query
- Bots should re-resolve revision IDs per run, never cache them
- Ensure the token's user can see the target revision
When it happens
Trigger: Calling differential.createinline with a truthy revisionID that does not exist, is 'D'-prefixed, or names a revision the acting user cannot see.
Common situations: Automated review bots attaching inline comments using revision IDs from older runs; restricted-space revisions; passing a PHID instead of the numeric ID.
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
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/31019455156950c5.
Report an issue: GitHub.