phacility/phabricator · error · HeraldInvalidConditionException

Second regular expression is invalid!

Error message

Second regular expression is invalid!

What it means

The second half of regexp-pair evaluation: once the key regexp matches a dictionary key, the adapter runs @preg_match($value_regexp, $value); if that returns false the value pattern is invalid and HeraldInvalidConditionException('Second regular expression is invalid!') is thrown. Note it fires only after a key matched, so a broken second pattern can lurk until a key first matches.

Source

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

        }
        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) {
          throw new HeraldInvalidConditionException(
            pht('Condition references a rule which does not exist!'));
        }

        $is_not = ($condition_type == self::CONDITION_NOT_RULE);
        $result = $engine->doesRuleMatch($rule, $this);

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Validate the second pattern standalone: php -r 'var_dump(@preg_match("/value-pattern/", "x"));' must not return false.
  2. Fix delimiters/syntax and re-save the rule.
  3. When generating pairs programmatically, validate both patterns with @preg_match(...) === false checks before saving.

Example fix

// before (value regexp missing delimiter)
["/^build-/", "nightly$"]

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

Strategy: validation

Validate before calling

// Validate the SECOND (value) regexp of the pair before saving:
if (@preg_match($value_regexp, '') === false) {
  // value regexp is invalid - fix before saving the condition
}

Prevention

When it happens

Trigger: The second (value) element of the JSON pair is an invalid PCRE pattern (missing delimiters, bad syntax) and evaluation reaches a dictionary entry whose key matches the first pattern.

Common situations: Same as other invalid-pattern cases: API-written values, delimiter or escaping mistakes, copy-pasted patterns from other regex dialects.

Related errors


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