phacility/phabricator · error · Exception
Rule '%s' is not a valid regular expression.
Error message
Rule '%s' is not a valid regular expression.
What it means
While distributing files to atomizers, Diviner runs each `rules` key from the book configuration through preg_match(). PHP's preg_match returns false for a malformed pattern, and this Exception is thrown for the first rule that fails. In practice it almost always means the `.book` JSON has a rule key that is not a valid PCRE pattern — most commonly missing the delimiter characters (`/.../`) that PHP requires.
Source
Thrown at src/applications/diviner/workflow/DivinerGenerateWorkflow.php:275
$this->log(pht('Done.')."\n");
}
private function getAtomizersForFiles(array $files) {
$rules = $this->getRules();
$exclude = $this->getExclude();
$atomizers = array();
foreach ($files as $file) {
foreach ($exclude as $pattern) {
if (preg_match($pattern, $file)) {
continue 2;
}
}
foreach ($rules as $rule => $atomizer) {
$ok = preg_match($rule, $file);
if ($ok === false) {
throw new Exception(
pht("Rule '%s' is not a valid regular expression.", $rule));
}
if ($ok) {
$atomizers[$file] = $atomizer;
continue;
}
}
}
return $atomizers;
}
private function getRules() {
return $this->getConfig('rules', array(
'/\\.diviner$/' => 'DivinerArticleAtomizer',
'/\\.php$/' => 'DivinerPHPAtomizer',
));
}View on GitHub (pinned to 5720a38cfe)
Solutions
- Wrap every rule key in delimiters: `"\\.php$"` becomes `"/\\.php$/"`
- Test each pattern in isolation: `php -r 'var_dump(preg_match("/PATTERN/", ""));'` should not print false
- Run a JSON lint on the `.book` file after editing to catch escaping damage
Example fix
// before (docs/book.book)
"rules": {"src/.*\\.php$": "DivinerPHPAtomizer"}
// after (PCRE delimiters added)
"rules": {"/src/.*\\.php$/": "DivinerPHPAtomizer"} Defensive patterns
Strategy: validation
Validate before calling
$rules = idx($book, 'rules', array());
foreach (array_keys($rules) as $rule) {
if (@preg_match($rule, '') === false) {
// Reject the config before Diviner runs: the pattern is not valid PCRE.
throw new Exception('Invalid regex in book config: '.$rule);
}
} Prevention
- Every rules key needs PCRE delimiters (e.g. "/\.php$/"), unlike JS/Python regex
- Test patterns standalone: php -r 'var_dump(preg_match("/YOUR_PATTERN/", ""));'
- Add a .book linter step to CI that runs the @preg_match pre-check on every rule
When it happens
Trigger: A `.book` file containing e.g. `"rules": {"\.php$": "DivinerPHPAtomizer"}` — the key lacks delimiters, so preg_match returns false. Also unbalanced parentheses/brackets, unknown modifiers after the closing delimiter, or a stray backslash.
Common situations: Authors writing regexes JSON-style (without delimiters) as in JS or Python; regexes that worked in another tool but were pasted into the `.book` file losing their delimiters; escaping mistakes through the double layer of JSON + PCRE (e.g. `\\.` needed for a literal dot).
Related errors
- The following regex is malformed and cannot be used: %s
- Specify a Diviner book configuration file with %s.
- Book configuration '%s' has name '%s', but book names must i
- Regular expression "%s" in Herald rule "%s" is not valid, or
- First regular expression is invalid!
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/d5ca0c634af6e10d.
Report an issue: GitHub.