{"record":{"id":"0d46c0e89c6ceb6b","repo":"phacility/phabricator","slug":"you-must-specify-at-least-one-daemon-to-start","errorCode":null,"errorMessage":"You must specify at least one daemon to start!","messagePattern":"You must specify at least one daemon to start!","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"warning","filePath":"src/infrastructure/daemon/PhutilDaemonOverseer.php","lineNumber":115,"sourceCode":"    $config = id(new PhutilJSONParser())->parse($config);\n\n    $this->libraries = idx($config, 'load');\n    $this->log = idx($config, 'log');\n    $this->daemonize = idx($config, 'daemonize');\n\n    $this->config = $config;\n\n    if (self::$instance) {\n      throw new Exception(\n        pht('You may not instantiate more than one Overseer per process.'));\n    }\n\n    self::$instance = $this;\n\n    $this->startEpoch = time();\n\n    if (!idx($config, 'daemons')) {\n      throw new PhutilArgumentUsageException(\n        pht('You must specify at least one daemon to start!'));\n    }\n\n    if ($this->log) {\n      // NOTE: Now that we're committed to daemonizing, redirect the error\n      // log if we have a `--log` parameter. Do this at the last moment\n      // so as many setup issues as possible are surfaced.\n      ini_set('error_log', $this->log);\n    }\n\n    if ($this->daemonize) {\n      // We need to get rid of these or the daemon will hang when we TERM it\n      // waiting for something to read the buffers. TODO: Learn how unix works.\n      fclose(STDOUT);\n      fclose(STDERR);\n      ob_start();\n\n      $pid = pcntl_fork();","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/infrastructure/daemon/PhutilDaemonOverseer.php#L97-L133","documentation":"PhutilDaemonOverseer's constructor requires a non-empty 'daemons' entry in its config array; this PhutilArgumentUsageException is that guard. It fires when an overseer process is started without being told which daemon(s) to run, i.e. a command-line or config usage mistake rather than a runtime failure.","triggerScenarios":"Constructing PhutilDaemonOverseer with a config array missing the 'daemons' key, or driving the daemon launch entry point with no daemon argument so the config is built empty.","commonSituations":"Custom wrapper scripts around phd that assemble the overseer config programmatically and forget the daemons entry; argv forwarding bugs in launch tooling; invoking the overseer binary directly instead of through phd.","solutions":["Pass at least one daemon to start, e.g. via the standard phd launch workflow.","If constructing PhutilDaemonOverseer yourself, set 'daemons' => array(...) in the config array.","Check any wrapper script's argument forwarding so daemon arguments reach the overseer."],"exampleFix":"// before\nnew PhutilDaemonOverseer(array('log' => $log_path));\n\n// after\nnew PhutilDaemonOverseer(array(\n  'daemons' => array('PhabricatorTaskmasterDaemon'),\n  'log' => $log_path,\n));","handlingStrategy":"validation","validationCode":"if (!idx($config, 'daemons')) {\n  throw new InvalidArgumentException(\n    'Provide at least one daemon in the overseer config.');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Launch daemons through the phd workflow rather than constructing the overseer directly.","When building the config array programmatically, assert the 'daemons' key is non-empty first."],"tags":["phabricator","daemons","overseer","cli","usage"],"backgroundTag":"missing-cli-argument","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}