{"record":{"id":"cda6837805c9b8ff","repo":"phacility/phabricator","slug":"specify-a-diviner-book-configuration-file-with-s","errorCode":null,"errorMessage":"Specify a Diviner book configuration file with %s.","messagePattern":"Specify a Diviner book configuration file with (.+?)\\.","errorType":"console","errorClass":"PhutilArgumentUsageException","httpStatus":null,"severity":"warning","filePath":"src/applications/diviner/workflow/DivinerWorkflow.php","lineNumber":22,"sourceCode":"\n  private $config;\n  private $bookConfigPath;\n\n  public function getBookConfigPath() {\n    return $this->bookConfigPath;\n  }\n\n  protected function getConfig($key, $default = null) {\n    return idx($this->config, $key, $default);\n  }\n\n  protected function getAllConfig() {\n    return $this->config;\n  }\n\n  protected function readBookConfiguration($book_path) {\n    if ($book_path === null) {\n      throw new PhutilArgumentUsageException(\n        pht(\n          'Specify a Diviner book configuration file with %s.',\n          '--book'));\n    }\n\n    $book_data = Filesystem::readFile($book_path);\n    $book = phutil_json_decode($book_data);\n\n    PhutilTypeSpec::checkMap(\n      $book,\n      array(\n        'name' => 'string',\n        'title' => 'optional string',\n        'short' => 'optional string',\n        'preface' => 'optional string',\n        'root' => 'optional string',\n        'uri.source' => 'optional string',\n        'rules' => 'optional map<regex, string>',","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/diviner/workflow/DivinerWorkflow.php#L4-L40","documentation":"DivinerWorkflow::readBookConfiguration() loads and validates the `.book` JSON that every Diviner workflow needs. When it is called with a null path — i.e. no `--book` was given — it throws this PhutilArgumentUsageException immediately, before touching the filesystem. Workflows such as `atomize` require `--book` explicitly because they have no discovery fallback.","triggerScenarios":"Running `diviner atomize` (or any workflow that calls readBookConfiguration($args->getArg('book'))) without the `--book` flag. Note that `generate` only hits this if it auto-discovers nothing or is invoked programmatically with a null book path.","commonSituations":"Assuming all workflows auto-discover books like `generate` does; scripts that call the workflow classes directly and pass a null path; renaming the `.book` file and not updating the command.","solutions":["Add `--book <path>` pointing at your `.book` file: `diviner atomize --book docs/book.book ...`","Verify the path is readable before running: `cat docs/book.book`","If invoking programmatically, never pass null; resolve the book path first"],"exampleFix":"# before\ndiviner atomize --atomizer DivinerPHPAtomizer src/\n# after\ndiviner atomize --book docs/book.book --atomizer DivinerPHPAtomizer src/","handlingStrategy":"validation","validationCode":"if ($args->getArg('book') === null) {\n  // atomize has no discovery fallback: require an explicit --book path.\n  $args->printHelpAndExit();\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember that only `generate` auto-discovers books; `atomize` requires --book","Check the .book path exists and is readable before invoking diviner","Centralize the diviner invocation (with flags) in one build script"],"tags":["diviner","cli","missing-argument","config","phabricator"],"backgroundTag":"missing-cli-argument","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}