phacility/phabricator · error · Exception

Field "changes" must be non-empty.

Error message

Field "changes" must be non-empty.

What it means

differential.creatediff requires a 'changes' parameter: an array of ArcanistDiffChange dictionaries, each inflated via ArcanistDiffChange::newFromDictionary and passed to DifferentialDiff::newFromRawChanges. The guard tests only for null ($change_data === null), so the exception 'Field "changes" must be non-empty.' fires when the key is absent or explicitly null.

Source

Thrown at src/applications/differential/conduit/DifferentialCreateDiffConduitAPIMethod.php:59

      'lintStatus'                => 'required '.$status_const,
      'unitStatus'                => 'required '.$status_const,
      'repositoryPHID'            => 'optional phid',

      'parentRevisionID'          => 'deprecated',
      'authorPHID'                => 'deprecated',
      'repositoryUUID'            => 'deprecated',
    );
  }

  protected function defineReturnType() {
    return 'nonempty dict';
  }

  protected function execute(ConduitAPIRequest $request) {
    $viewer = $request->getUser();
    $change_data = $request->getValue('changes');
    if ($change_data === null) {
      throw new Exception(pht('Field "changes" must be non-empty.'));
    }

    $changes = array();
    foreach ($change_data as $dict) {
      $changes[] = ArcanistDiffChange::newFromDictionary($dict);
    }

    $diff = DifferentialDiff::newFromRawChanges($viewer, $changes);

    // TODO: Remove repository UUID eventually; for now continue writing
    // the UUID. Note that we'll overwrite it below if we identify a
    // repository, and `arc` no longer sends it. This stuff is retained for
    // backward compatibility.

    $repository_uuid = $request->getValue('repositoryUUID');
    $repository_phid = $request->getValue('repositoryPHID');
    if ($repository_phid) {
      $repository = id(new PhabricatorRepositoryQuery())

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Always include 'changes' as an array with at least one change dictionary in the arc format
  2. If your local parser produced zero changes, abort before calling - an empty diff is not worth creating
  3. Compare your payload against a real 'arc diff --conduit' request captured with --conduit-uri debugging
  4. Note the server only rejects null: an empty array passes but creates a useless empty diff, so validate client-side too

Example fix

// before
$params = array(
  'sourceMachine' => 'build01',
  'sourcePath' => '/srv/build',
);

// after
$params = array(
  'sourceMachine' => 'build01',
  'sourcePath' => '/srv/build',
  'changes' => $parser->getChangeDictionaries(), // >= 1 entry
);
Defensive patterns

Strategy: validation

Validate before calling

if (!isset($params['changes']) || !is_array($params['changes'])
    || count($params['changes']) === 0) {
  throw new InvalidArgumentException(
    'changes must be a non-empty array of change dictionaries');
}

Try / catch

try {
  $result = $client->callMethodSynchronous('differential.creatediff', $params);
} catch (ConduitClientException $ex) {
  if (strpos($ex->getMessage(), 'must be non-empty') !== false) {
    // client payload bug: fix the changes key, do not retry unchanged
    throw new RuntimeException('Bad diff payload', 0, $ex);
  }
  throw $ex;
}

Prevention

When it happens

Trigger: Calling differential.creatediff with no 'changes' key in the parameters dict, or with 'changes' => null because local diff parsing produced nothing.

Common situations: Custom tooling that mimics the arc payload but skips the changes key when the working copy is clean; a wrapper that assigns null as a default for missing parser output; version drift where an older client sent a differently-named key.

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/47a6bcd5fc883ba0. Report an issue: GitHub.