phacility/phabricator · error · HeraldInvalidConditionException

First regular expression is invalid!

Error message

First regular expression is invalid!

What it means

In a regexp-pair condition, the adapter iterates the field's dictionary and runs @preg_match($key_regexp, $key). If preg_match returns false (invalid pattern — delimiter, syntax, or modifier errors), it throws HeraldInvalidConditionException('First regular expression is invalid!'). The failure is lazy: it only surfaces when rule evaluation actually reaches a key/value pair.

Source

Thrown at src/applications/herald/adapter/HeraldAdapter.php:574

        $regexp_pair = null;
        try {
          $regexp_pair = phutil_json_decode($condition_value);
        } catch (PhutilJSONParserException $ex) {
          throw new HeraldInvalidConditionException(
            pht('Regular expression pair is not valid JSON!'));
        }
        if (count($regexp_pair) != 2) {
          throw new HeraldInvalidConditionException(
            pht('Regular expression pair is not a pair!'));
        }

        $key_regexp   = array_shift($regexp_pair);
        $value_regexp = array_shift($regexp_pair);

        foreach ((array)$field_value as $key => $value) {
          $key_matches = @preg_match($key_regexp, $key);
          if ($key_matches === false) {
            throw new HeraldInvalidConditionException(
              pht('First regular expression is invalid!'));
          }
          if ($key_matches) {
            $value_matches = @preg_match($value_regexp, $value);
            if ($value_matches === false) {
              throw new HeraldInvalidConditionException(
                pht('Second regular expression is invalid!'));
            }
            if ($value_matches) {
              return true;
            }
          }
        }
        return false;
      case self::CONDITION_RULE:
      case self::CONDITION_NOT_RULE:
        $rule = $engine->getRule($condition_value);
        if (!$rule) {

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Wrap the key pattern in delimiters and verify it: php -r 'var_dump(@preg_match("/your-pattern/", "x"));' must not return false.
  2. Re-save the rule in the UI, testing the pattern in the condition editor.
  3. Remove unsupported modifiers and use PCRE syntax.

Example fix

// before (no delimiters on the key regexp)
["^build-", "/nightly/"]

// after
["/^build-/", "/nightly/"]
Defensive patterns

Strategy: validation

Validate before calling

// Validate the FIRST (key) regexp of the pair before saving:
try {
  list($key_regexp, $value_regexp) = phutil_json_decode($value);
} catch (PhutilJSONParserException $ex) {
  // handle 814 first
}
if (@preg_match($key_regexp, '') === false) {
  // key regexp is invalid - fix before saving the condition
}

Prevention

When it happens

Trigger: The first (key) element of the JSON pair is not a valid PCRE pattern — e.g. 'foo' without delimiters, unbalanced delimiters, or an unknown modifier — and a rule evaluation matches the condition against a non-empty dictionary.

Common situations: Users enter bare patterns without /.../ delimiters in API-created conditions; escaping is lost one too many times through json_encode/manual editing; modifiers from other regex flavors (e.g. Python) are used.

Related errors


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