phacility/phabricator · error · ConduitException
ERR-NEED-DIFF
ERR-NEED-DIFF
Error message
ERR-NEED-DIFF
What it means
Thrown by differential.createinline when neither revisionID nor diffID is supplied. The method needs at least one of the two to resolve the revision and diff that the inline comment attaches to; with both falsy it bails immediately with ConduitException('ERR-NEED-DIFF').
Source
Thrown at src/applications/differential/conduit/DifferentialCreateInlineConduitAPIMethod.php:78
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();
} else {
// Given neither, bail.
throw new ConduitException('ERR-NEED-DIFF');
}
$file = $request->getValue('filePath');
if (!$file) {
throw new ConduitException('ERR-NEED-FILE');
}
$changes = id(new DifferentialChangeset())->loadAllWhere(
'diffID = %d',
$did);
$cid = null;
foreach ($changes as $id => $change) {
if ($file == $change->getFilename()) {
$cid = $id;
}
}
if ($cid == null) {
throw new ConduitException('ERR-BAD-FILE');
}View on GitHub (pinned to 5720a38cfe)
Solutions
- Always supply at least one of revisionID or diffID
- Validate the parameters before the call and skip rows with no IDs, logging them for follow-up
- Prefer revisionID so the server resolves the active diff itself
- Distinguish this client error from ERR-BAD-DIFF in your handling - retrying will not help
Example fix
// before $params = array( 'filePath' => 'src/app.php', 'content' => 'Note.', ); // after $params = array( 'revisionID' => 789, 'filePath' => 'src/app.php', 'content' => 'Note.', );
Defensive patterns
Strategy: validation
Validate before calling
if (empty($params['revisionID']) && empty($params['diffID'])) {
throw new InvalidArgumentException(
'createinline requires revisionID or diffID');
} Prevention
- Require at least one of revisionID/diffID in the wrapper's own contract
- Skip and log input rows lacking both IDs
- Prefer revisionID so the server resolves the active diff
When it happens
Trigger: Calling differential.createinline with neither revisionID nor diffID, or with both set to 0/null/empty string (e.g. a wrapper that read missing values from a config file and passed them through).
Common situations: Batch tools whose input rows sometimes lack the IDs; environment-specific configuration where the revision/diff variables are never populated; refactors that renamed the keys.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- ERR-NEED-FILE
- Field "changes" must be non-empty.
- ERR-BAD-REVISION
- ERR-BAD-FILE
- Field "raw_diff" must be non-empty.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/28b284fc2cc88f74.
Report an issue: GitHub.