phacility/phabricator · error · ConduitException
ERR_NOT_FOUND
ERR_NOT_FOUND
Error message
ERR_NOT_FOUND
What it means
Thrown by the differential.closerevision Conduit method. It runs a viewer-policy-filtered DifferentialRevisionQuery (with reviewers attached) on the revisionID parameter, then applies a DifferentialRevisionCloseTransaction through DifferentialTransactionEditor. If the query returns no revision (the ID does not exist or the acting user cannot see it), ConduitException('ERR_NOT_FOUND') is thrown before any transaction is applied.
Source
Thrown at src/applications/differential/conduit/DifferentialCloseConduitAPIMethod.php:50
}
protected function defineErrorTypes() {
return array(
'ERR_NOT_FOUND' => pht('Revision was not found.'),
);
}
protected function execute(ConduitAPIRequest $request) {
$viewer = $request->getUser();
$id = $request->getValue('revisionID');
$revision = id(new DifferentialRevisionQuery())
->withIDs(array($id))
->setViewer($viewer)
->needReviewers(true)
->executeOne();
if (!$revision) {
throw new ConduitException('ERR_NOT_FOUND');
}
$xactions = array();
$xactions[] = id(new DifferentialTransaction())
->setTransactionType(
DifferentialRevisionCloseTransaction::TRANSACTIONTYPE)
->setNewValue(true);
$content_source = $request->newContentSource();
$editor = id(new DifferentialTransactionEditor())
->setActor($viewer)
->setContentSource($request->newContentSource())
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true);
$editor->applyTransactions($revision, $xactions);
View on GitHub (pinned to 5720a38cfe)
Solutions
- Pass revisionID as the bare integer ID (123), not 'D123' and not a PHID
- Confirm the revision exists and is visible to the same token by calling differential.query with ids=[id] first
- Check the revision's view policy and space in the web UI, and run the call with a token from a user who can see it
- In automation, treat ERR_NOT_FOUND as non-fatal: log it and continue instead of aborting the whole hook
Example fix
// before
$client->callMethodSynchronous('differential.closerevision', array(
'revisionID' => 'D123',
));
// after
$client->callMethodSynchronous('differential.closerevision', array(
'revisionID' => 123,
)); Defensive patterns
Strategy: try-catch
Validate before calling
// PHP conduit client: confirm visibility with the same token first.
$found = $client->callMethodSynchronous(
'differential.query',
array('ids' => array((int)$id)));
if (!$found) {
// nothing to close; skip
return;
} Try / catch
try {
$client->callMethodSynchronous('differential.closerevision',
array('revisionID' => (int)$id));
} catch (ConduitClientException $ex) {
if ($ex->getErrorCode() === 'ERR_NOT_FOUND') {
// revision absent or invisible: log, continue
} else {
throw $ex;
}
} Prevention
- Normalize revision IDs to bare integers (strip the leading 'D') before calling
- Pre-check existence with differential.query using the same conduit token
- In automation, treat close-not-found as a warning, not a pipeline failure
When it happens
Trigger: Calling conduit method differential.closerevision with a revisionID that does not exist, passing 'D123' or a PHID instead of the bare integer, passing null/0, or closing a revision hidden from the caller by object or space visibility policy.
Common situations: Post-merge automation that closes revisions using IDs scraped from commit messages; bot accounts whose conduit token belongs to a user without visibility on the revision; typos when transcribing revision numbers; the revision was deleted after its ID was captured.
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/afe5cd0f865a657b.
Report an issue: GitHub.