{"record":{"id":"68992742a66b4d63","repo":"phacility/phabricator","slug":"err-empty","errorCode":"err:empty","errorMessage":"Your message does not contain any body text or attachments, so this server can not do anything useful with it. Make sure comment text appears at the top of your message: quoted replies, inline text, and signatures are discarded and ignored.","messagePattern":"Your message does not contain any body text or attachments, so this server can not do anything useful with it\\. Make sure comment text appears at the top of your message: quoted replies, inline text, and signatures are discarded and ignored\\.","errorType":"exception","errorClass":"PhabricatorMetaMTAReceivedMailProcessingException","httpStatus":null,"severity":"warning","filePath":"src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php","lineNumber":436,"sourceCode":"    $attachments = $this->getAttachments();\n\n    if (strlen($body) || $attachments) {\n      return;\n    }\n\n    // Only send an error email if the user is talking to just Phabricator.\n    // We can assume if there is only one \"To\" address it is a Phabricator\n    // address since this code is running and everything.\n    $is_direct_mail = (count($this->getToAddresses()) == 1) &&\n                      (count($this->getCCAddresses()) == 0);\n\n    if ($is_direct_mail) {\n      $status_code = MetaMTAReceivedMailStatus::STATUS_EMPTY;\n    } else {\n      $status_code = MetaMTAReceivedMailStatus::STATUS_EMPTY_IGNORED;\n    }\n\n    throw new PhabricatorMetaMTAReceivedMailProcessingException(\n      $status_code,\n      pht(\n        'Your message does not contain any body text or attachments, so '.\n        'this server can not do anything useful with it. Make sure comment '.\n        'text appears at the top of your message: quoted replies, inline '.\n        'text, and signatures are discarded and ignored.'));\n  }\n\n  private function sendExceptionMail(\n    Exception $ex,\n    PhabricatorUser $viewer = null) {\n\n    // If we've failed to identify a legitimate sender, we don't send them\n    // an error message back. We want to avoid sending mail to unverified\n    // addresses. See T12491.\n    if (!$viewer) {\n      return;\n    }","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php#L418-L454","documentation":"dropEmptyMail() throws when the cleaned body (getCleanTextBody()) has no text and there are no attachments: there is literally nothing for any receiver to act on. The status distinguishes direct mail (exactly one To, zero CC → STATUS_EMPTY, user gets the helpful error email) from multi-recipient mail (STATUS_EMPTY_IGNORED, silently ignored because other humans got the mail). The message text coaches users that Phabricator strips quoted replies, inline text, and signatures — only top-of-message text counts.","triggerScenarios":"A reply whose entire content lives below the quoted original (everything above the first quote marker was blank), a message containing only an image pasted into a signature/HTML part not extracted as attachment, or an empty mail. With count(getToAddresses())==1 and count(getCCAddresses())==0 the direct-mail variant bounces the error back to the user.","commonSituations":"Users replying with answers typed inline next to quoted lines; top-posting clients configured to strip everything above a signature delimiter so the clean body ends up empty; mobile clients sending only HTML with the text alternative empty; reply chains where the user wrote only 'Ack' inside the quoted block.","solutions":["Reply with your comment text at the very top of the message, above the quoted original — Phabricator discards everything from the first quoted line down.","If the content is a file, attach it as a real attachment rather than embedding it in HTML/signature.","If it bounced as STATUS_EMPTY, simply resend with the text at top; the object state is unchanged (nothing was applied).","Admins: for recurring offenders, point users at the 'Reply Instructions' setting so outbound mail explains the top-posting requirement."],"exampleFix":"// before: reply body after cleaning is empty\n// \"> Alincoln: can you approve D123?\"  (everything quoted) -> err:empty\n\n// after: comment text above the quote\n// \"Approved, thanks!\"  \n// \"> Alinclair: can you approve D123?\" -> comment applied","handlingStrategy":"validation","validationCode":"// Mirror dropEmptyMail() before ingesting: require non-empty clean body or attachments.\n$clean = $body_parser->getCleanTextBody(); // strips quotes/signatures like Phabricator does\nif (!strlen(trim($clean)) && !$message->getAttachments()) {\n  // reject at the boundary with 'put your comment at the top' guidance\n}","typeGuard":null,"tryCatchPattern":"try {\n  $received_mail->processIncomingMail($sender);\n} catch (PhabricatorMetaMTAReceivedMailProcessingException $ex) {\n  if ($ex->getStatusCode() === MetaMTAReceivedMailStatus::STATUS_EMPTY) {\n    // direct mail bounced: nothing was applied, user can safely resend with top text\n    notify_user_about_top_posting();\n    return;\n  }\n  throw $ex;\n}","preventionTips":["Type replies above the quoted original; Phabricator discards everything below the first quote.","Send files as real attachments, never embedded in HTML bodies or signatures.","Treat STATUS_EMPTY as non-destructive — resending with content at top is always safe."],"tags":["metamta","email","empty-body","mail-parsing","inbound-mail"],"backgroundTag":"empty-email-body","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}