phacility/phabricator · warning · PhutilArgumentUsageException

Book configuration '%s' has name '%s', but book names must i

Error message

Book configuration '%s' has name '%s', but book names must include only lowercase letters and hyphens.

What it means

When loading a book configuration, Diviner enforces that the `name` field matches `/^[a-z][a-z-]*\z/`. The name becomes part of the on-disk atom cache path and generated URIs, so uppercase letters, digits, underscores, or a leading hyphen are rejected with this PhutilArgumentUsageException. The message includes both the offending book path and the rejected name.

Source

Thrown at src/applications/diviner/workflow/DivinerWorkflow.php:55

        'preface' => 'optional string',
        'root' => 'optional string',
        'uri.source' => 'optional string',
        'rules' => 'optional map<regex, string>',
        'exclude' => 'optional regex|list<regex>',
        'groups' => 'optional map<string, map<string, wild>>',
      ));

    // If the book specifies a "root", resolve it; otherwise, use the directory
    // the book configuration file lives in.
    $full_path = dirname(Filesystem::resolvePath($book_path));
    if (empty($book['root'])) {
      $book['root'] = '.';
    }
    $book['root'] = Filesystem::resolvePath($book['root'], $full_path);

    if (!preg_match('/^[a-z][a-z-]*\z/', $book['name'])) {
      $name = $book['name'];
      throw new PhutilArgumentUsageException(
        pht(
          "Book configuration '%s' has name '%s', but book names must ".
          "include only lowercase letters and hyphens.",
          $book_path,
          $name));
    }

    foreach (idx($book, 'groups', array()) as $group) {
      PhutilTypeSpec::checkMap(
        $group,
        array(
          'name' => 'string',
          'include' => 'optional regex|list<regex>',
        ));
    }

    $this->bookConfigPath = $book_path;
    $this->config = $book;

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Rewrite the name to lowercase letters and hyphens only: "PhabDocs" -> "phab-docs"
  2. Keep `title` (human-readable) separate — the constraint applies only to `name`
  3. After renaming, clear stale `.divinercache` directories named after the old book

Example fix

// before (docs/book.book)
"name": "PhabricatorDocs",
// after
"name": "phabricator-docs",
Defensive patterns

Strategy: validation

Validate before calling

$name = idx($book, 'name');
if (!preg_match('/^[a-z][a-z-]*\z/', $name)) {
  // Fix the name before shipping the .book file.
  $book['name'] = strtolower(preg_replace('/[^a-z-]+/i', '-', $name));
}

Prevention

When it happens

Trigger: A `.book` JSON whose `name` is e.g. "PhabDocs", "docs2", "my_book", or "-docs". Any character outside a-z and hyphen, or a name not starting with a letter, triggers it.

Common situations: Naming the book after the product with CamelCase ("PhabricatorDocs"); converting a repo name like "my_docs" directly into a book name; renaming a book later and forgetting the constraint.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/633135591884c64b. Report an issue: GitHub.