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

  1. Always supply at least one of revisionID or diffID
  2. Validate the parameters before the call and skip rows with no IDs, logging them for follow-up
  3. Prefer revisionID so the server resolves the active diff itself
  4. 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

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


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/28b284fc2cc88f74. Report an issue: GitHub.