{"record":{"id":"6ba6bac5bc221e23","repo":"phacility/phabricator","slug":"field-corpus-must-be-non-empty","errorCode":null,"errorMessage":"Field \"corpus\" must be non-empty.","messagePattern":"Field \"corpus\" must be non-empty\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/differential/conduit/DifferentialParseCommitMessageConduitAPIMethod.php","lineNumber":37,"sourceCode":"  }\n\n  protected function defineReturnType() {\n    return 'nonempty dict';\n  }\n\n  protected function execute(ConduitAPIRequest $request) {\n    $viewer = $this->getViewer();\n\n    $parser = DifferentialCommitMessageParser::newStandardParser($viewer);\n\n    $is_partial = $request->getValue('partial');\n    if ($is_partial) {\n      $parser->setRaiseMissingFieldErrors(false);\n    }\n\n    $corpus = $request->getValue('corpus');\n    if ($corpus === null || !strlen($corpus)) {\n      throw new Exception(pht('Field \"corpus\" must be non-empty.'));\n    }\n    $field_map = $parser->parseFields($corpus);\n\n    $errors = $parser->getErrors();\n    $xactions = $parser->getTransactions();\n\n    $revision_id_value = idx(\n      $field_map,\n      DifferentialRevisionIDCommitMessageField::FIELDKEY);\n    $revision_id_valid_domain = PhabricatorEnv::getProductionURI('');\n\n    return array(\n      'errors' => $errors,\n      'fields' => $field_map,\n      'revisionIDFieldInfo' => array(\n        'value' => $revision_id_value,\n        'validDomain' => $revision_id_valid_domain,\n      ),","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/differential/conduit/DifferentialParseCommitMessageConduitAPIMethod.php#L19-L55","documentation":"differential.parsecommitmessage takes the raw commit message in the corpus parameter and parses it into fields. The method rejects the call before parsing when corpus is null or a zero-length string, because an empty message can never yield field values or useful validation results.","triggerScenarios":"Calling differential.parsecommitmessage with corpus omitted, set to null, or set to '' — typically automation running over a commit whose message is empty, or code that reads the message from a file or stdin before the read finished.","commonSituations":"Hook scripts that run on merges with empty messages; async file reads where the message variable is still null at call time; ported scripts that assumed corpus was optional.","solutions":["Pass the full raw commit message text in corpus.","Skip the call entirely when the message is empty; an empty corpus is never useful.","If messages may be whitespace-only, trim first and treat an empty trimmed result as 'no message'."],"exampleFix":"// before\n$client->callMethodSynchronous('differential.parsecommitmessage', array(\n  'corpus' => $message, // $message may be null or ''\n));\n\n// after\nif ($message !== null && trim($message) !== '') {\n  $result = $client->callMethodSynchronous(\n    'differential.parsecommitmessage',\n    array('corpus' => $message));\n}","handlingStrategy":"validation","validationCode":"if ($corpus === null || trim($corpus) === '') {\n  // nothing to parse; skip the conduit call\n  return array();\n}\n$result = $client->callMethodSynchronous(\n  'differential.parsecommitmessage',\n  array('corpus' => $corpus));","typeGuard":"function isNonEmptyCorpus($text) {\n  return is_string($text) && strlen(trim($text)) > 0;\n}","tryCatchPattern":"try {\n  $parsed = $client->callMethodSynchronous(\n    'differential.parsecommitmessage', $params);\n} catch (ConduitClientException $ex) {\n  if (strpos($ex->getMessage(), 'corpus') !== false) {\n    // empty corpus: fix the caller, do not retry\n  } else {\n    throw $ex;\n  }\n}","preventionTips":["Trim and length-check the commit message before parsing.","Treat an empty message as a skip, not an API call.","Finish reading the message before invoking the method."],"tags":["phabricator","conduit","differential","commit-message","validation"],"backgroundTag":"empty-request-parameter","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}