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
- Always include 'changes' as an array with at least one change dictionary in the arc format
- If your local parser produced zero changes, abort before calling - an empty diff is not worth creating
- Compare your payload against a real 'arc diff --conduit' request captured with --conduit-uri debugging
- 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
- Assert the local parser produced at least one change before submitting
- Model payloads on a captured arc request
- Treat an empty changes list as an upstream failure, not a submit input
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
- Field "raw_diff" must be non-empty.
- ERR-BAD-DIFF
- ERR-NEED-DIFF
- ERR-NEED-FILE
- The raw diff you have submitted is too large to parse (it af
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/47a6bcd5fc883ba0.
Report an issue: GitHub.