{"record":{"id":"ff470fd25b98a930","repo":"phacility/phabricator","slug":"s-subprocess-exited-before-emitting-a-protocol-fr","errorCode":null,"errorMessage":"%s subprocess exited before emitting a protocol frame.","messagePattern":"(.+?) subprocess exited before emitting a protocol frame\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php","lineNumber":84,"sourceCode":"\n      $exec_message = $exec_channel->read();\n      if ($exec_message !== null) {\n        $messages = $exec_protocol->writeData($exec_message);\n        if ($messages) {\n          $message = head($messages);\n          $raw = $message['raw'];\n\n          // Write the greeting frame to the client.\n          $io_channel->write($raw);\n\n          // Kill the subprocess.\n          $future->resolveKill();\n          break;\n        }\n      }\n\n      if (!$exec_channel->isOpenForReading()) {\n        throw new Exception(\n          pht(\n            '%s subprocess exited before emitting a protocol frame.',\n            'svnserve'));\n      }\n    }\n\n    $io_protocol = new DiffusionSubversionWireProtocol();\n    while (true) {\n      PhutilChannel::waitForAny(array($io_channel));\n      $io_channel->update();\n\n      $in_message = $io_channel->read();\n      if ($in_message !== null) {\n        $this->peekBuffer .= $in_message;\n        if (strlen($this->peekBuffer) > (1024 * 1024)) {\n          throw new Exception(\n            pht(\n              'Client transmitted more than 1MB of data without transmitting '.","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php#L66-L102","documentation":"identifyRepository() launches 'svnserve -t' (sudo'd to the daemon user) just to capture the server greeting frame; if the exec channel closes before any frame arrives, the subprocess died instantly. This is almost always environmental: svnserve is not installed, not on the PATH the SSH session exposes, or crashes immediately as the executing user.","triggerScenarios":"phabricator-user or daemon-user environment cannot find the svnserve binary; the subversion server package is missing on the application host; svnserve exists but is not executable by the sudo target user.","commonSituations":"Fresh installs where subversion tools were never installed; non-interactive sshd sessions with a minimal PATH requiring 'environment.append-paths'; OS upgrades that removed or relocated the binary.","solutions":["Install the subversion server package and confirm 'svnserve --version' runs","Add the svnserve binary's directory to the 'environment.append-paths' Phabricator config so SSH sessions can resolve it","Reproduce as the executing user (sudo -u <daemon user> svnserve --version) and fix permissions or PATH based on what fails","Check the sudo rule PhabricatorDaemon::sudoCommandAsDaemonUser relies on when the workflow is not running as root"],"exampleFix":"# before: sshd starts sessions with a minimal PATH; svnserve lives in /usr/local/bin\n$ which svnserve\n(empty)\n\n# after: extend the search path Phabricator uses for subprocesses\n$ ./bin/config set environment.append-paths '[\"/usr/local/bin\"]'\n$ which svnserve\n/usr/local/bin/svnserve","handlingStrategy":"validation","validationCode":"$svnserve = Filesystem::resolveBinary('svnserve');\nif (!$svnserve) {\n  throw new Exception(\n    pht('svnserve not found; install it and extend environment.append-paths.'));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run Phabricator's environment/smoke checks after OS package changes on hosts serving SVN","Pin and monitor subversion binaries; verify the daemon user can execute svnserve during deploy"],"tags":["phabricator","svn","svnserve","subprocess","path","environment"],"backgroundTag":"subprocess-exited-unexpectedly","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}