{"record":{"id":"ee174dc9f168b776","repo":"phacility/phabricator","slug":"field-data-must-be-non-empty","errorCode":null,"errorMessage":"Field \"data\" must be non-empty.","messagePattern":"Field \"data\" must be non-empty\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/differential/conduit/DifferentialSetDiffPropertyConduitAPIMethod.php","lineNumber":35,"sourceCode":"      'name'    => 'required string',\n      'data'    => 'required string',\n    );\n  }\n\n  protected function defineReturnType() {\n    return 'void';\n  }\n\n  protected function defineErrorTypes() {\n    return array(\n      'ERR_NOT_FOUND' => pht('Diff was not found.'),\n    );\n  }\n\n  protected function execute(ConduitAPIRequest $request) {\n    $data = $request->getValue('data');\n    if ($data === null || !strlen($data)) {\n      throw new Exception(pht('Field \"data\" must be non-empty.'));\n    }\n\n    $diff_id = $request->getValue('diff_id');\n    if ($diff_id === null) {\n      throw new Exception(pht('Field \"diff_id\" must be non-null.'));\n    }\n\n    $name = $request->getValue('name');\n    if ($name === null || !strlen($name)) {\n      throw new Exception(pht('Field \"name\" must be non-empty.'));\n    }\n\n    $data = json_decode($data, true);\n\n    self::updateDiffProperty($diff_id, $name, $data);\n  }\n\n  private static function updateDiffProperty($diff_id, $name, $data) {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/differential/conduit/DifferentialSetDiffPropertyConduitAPIMethod.php#L17-L53","documentation":"differential.setdiffproperty stores a named property on a diff; data must be a non-empty JSON-encoded string, because the method json_decode()s it right after this check. Null or a zero-length string is rejected before anything is stored.","triggerScenarios":"Sending data as null or '' — commonly a payload built from empty input, a raw array sent where the API expects a string, or a default empty-string value that was never replaced.","commonSituations":"Callers that pass arrays directly instead of json_encode()ing them; code paths that compute the property payload from empty collections; scripts that only fill in name and diff_id.","solutions":["Always JSON-encode the payload: json_encode($value) yields non-empty text even for empty containers ('{}' or '[]').","Guard before the call: if data is null or strlen(data) is 0, skip the call or default to '{}'.","Confirm you send a string, not a raw array or null."],"exampleFix":"// before\n$params = array(\n  'diff_id' => $diff_id,\n  'name' => 'arc:lint',\n  'data' => $data, // $data may be null or ''\n);\n\n// after\n$payload = ($value === null) ? new stdClass() : $value;\n$params = array(\n  'diff_id' => $diff_id,\n  'name' => 'arc:lint',\n  'data' => json_encode($payload), // always a non-empty string\n);","handlingStrategy":"validation","validationCode":"$data = json_encode($payload);\nif (!is_string($data) || strlen($data) === 0) {\n  throw new InvalidArgumentException(\n    'Property payload must encode to a non-empty string.');\n}\n$params['data'] = $data;","typeGuard":"function isEncodablePayload($value) {\n  $json = json_encode($value);\n  return is_string($json) && strlen($json) > 0;\n}","tryCatchPattern":"try {\n  $client->callMethodSynchronous('differential.setdiffproperty', $params);\n} catch (ConduitClientException $ex) {\n  if (strpos($ex->getMessage(), '\"data\" must be non-empty') !== false) {\n    // rebuild payload with json_encode() and retry once\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Always json_encode() the payload before sending.","Send at least '{}' for empty objects.","Send data as a string, never a raw array or null."],"tags":["phabricator","conduit","differential","diff-property","validation"],"backgroundTag":"empty-request-parameter","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}