{"record":{"id":"b970ce8d1644cc2a","repo":"phacility/phabricator","slug":"received-multipart-form-data-request-with-no-bo","errorCode":null,"errorMessage":"Received \"multipart/form-data\" request with no \"boundary\".","messagePattern":"Received \"multipart/form-data\" request with no \"boundary\"\\.","errorType":"validation","errorClass":"Exception","httpStatus":500,"severity":"error","filePath":"src/aphront/multipartparser/AphrontMultipartParser.php","lineNumber":48,"sourceCode":"    if (!preg_match('(^multipart/form-data)', $content_type)) {\n      throw new Exception(\n        pht(\n          'Expected \"multipart/form-data\" content type when executing a '.\n          'multipart body read.'));\n    }\n\n    $type_parts = preg_split('(\\s*;\\s*)', $content_type);\n    $boundary = null;\n    foreach ($type_parts as $type_part) {\n      $matches = null;\n      if (preg_match('(^boundary=(.*))', $type_part, $matches)) {\n        $boundary = $matches[1];\n        break;\n      }\n    }\n\n    if ($boundary === null) {\n      throw new Exception(\n        pht('Received \"multipart/form-data\" request with no \"boundary\".'));\n    }\n\n    $this->parts = array();\n    $this->part = null;\n\n    $this->buffer = '';\n    $this->boundary = $boundary;\n\n    // We're looking for a (usually empty) body before the first boundary.\n    $this->state = 'bodynewline';\n  }\n\n  public function continueParse($bytes) {\n    $this->buffer .= $bytes;\n\n    $continue = true;\n    while ($continue) {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/aphront/multipartparser/AphrontMultipartParser.php#L30-L66","documentation":"Thrown by 'bin/repository unpublish' when the resolved repository set does not contain exactly one repository. Unpublish removes all feed stories and notifications a repository generated during import, so it deliberately acts on a single repository; passing zero, two, or more resolved repositories is rejected. Note that loadLocalRepositories() also filters to repositories hosted on the current device, so a valid name on the wrong device can resolve to zero and trigger this same error (with a locality rejection reason surfaced separately).","triggerScenarios":"Running 'bin/repository unpublish' with no arguments, with multiple monikers ('bin/repository unpublish R1 R2'), or with one identifier that the device-locality filter removes because the repository is not served by this cluster device: count($repositories) !== 1 at PhabricatorRepositoryManagementUnpublishWorkflow.php:47 throws.","commonSituations":"Cleanups scripted against the wrong host (repository not local to this device); accidental glob expansion passing several repos; forgetting the repository argument entirely; typo'd monikers resolving to zero.","solutions":["Pass exactly one repository identifier (monogram like R123, callsign, or UUID) to the command.","If the name is correct but the count is still wrong, run the command on a device that actually hosts the repository (check Almanac bindings).","Quote arguments in scripts to prevent shell globs expanding into multiple repositories."],"exampleFix":"# before\nbin/repository unpublish R1 R2\n\n# after\nbin/repository unpublish R1","handlingStrategy":"validation","validationCode":"# Pass exactly one quoted identifier and verify it resolves locally:\nif [ \"$(echo $REPOS | wc -w)\" -ne 1 ]; then echo 'need exactly one repository' >&2; exit 2; fi\nbin/repository unpublish \"$REPOS\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Quote the repository argument to defeat shell globbing.","Run unpublish on a device that hosts the repository."],"tags":["phabricator","cli","argument-validation","repository-management","unpublish"],"backgroundTag":"wrong-argument-count","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}