{"record":{"id":"fdf4a69822e80c43","repo":"phacility/phabricator","slug":"the-regular-expression-pair-s-must-have-exactly","errorCode":null,"errorMessage":"The regular expression pair \"%s\" must have exactly two elements.","messagePattern":"The regular expression pair \"(.+?)\" must have exactly two elements\\.","errorType":"validation","errorClass":"HeraldInvalidConditionException","httpStatus":null,"severity":"error","filePath":"src/applications/herald/adapter/HeraldAdapter.php","lineNumber":643,"sourceCode":"              'must have enclosing characters (e.g. \"@/path/to/file@\", not '.\n              '\"/path/to/file\") and be syntactically correct.',\n              $condition_value));\n        }\n        break;\n      case self::CONDITION_REGEXP_PAIR:\n        $json = null;\n        try {\n          $json = phutil_json_decode($condition_value);\n        } catch (PhutilJSONParserException $ex) {\n          throw new HeraldInvalidConditionException(\n            pht(\n              'The regular expression pair \"%s\" is not valid JSON. Enter a '.\n              'valid JSON array with two elements.',\n              $condition_value));\n        }\n\n        if (count($json) != 2) {\n          throw new HeraldInvalidConditionException(\n            pht(\n              'The regular expression pair \"%s\" must have exactly two '.\n              'elements.',\n              $condition_value));\n        }\n\n        $key_regexp = array_shift($json);\n        $val_regexp = array_shift($json);\n\n        $key_ok = @preg_match($key_regexp, '');\n        if ($key_ok === false) {\n          throw new HeraldInvalidConditionException(\n            pht(\n              'The first regexp in the regexp pair, \"%s\", is not a valid '.\n              'regexp.',\n              $key_regexp));\n        }\n","sourceCodeStart":625,"sourceCodeEnd":661,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/herald/adapter/HeraldAdapter.php#L625-L661","documentation":"Thrown by HeraldAdapter::willSaveCondition() for CONDITION_REGEXP_PAIR after the value parsed successfully as JSON but count($json) != 2. The pair condition semantically requires exactly two elements — a key regexp and a value regexp — so arrays with fewer or more elements are rejected even though they are valid JSON.","triggerScenarios":"Saving a regexp-pair condition whose JSON decodes to an array of length other than 2: [] , [\"@only-key@\"], or [\"@a@\", \"@b@\", \"@c@\"]. The count() check runs immediately after phutil_json_decode() succeeds.","commonSituations":"Users assume the pair is a list and add several patterns, or leave a placeholder/empty array while drafting a rule. Occasionally a JSON array containing a nested array (e.g. [[\"a\"], \"b\"]) still passes count but fails the later regexp checks.","solutions":["Make the value a JSON array with exactly two string elements: [\"@key@\", \"@value@\"].","Combine multiple key patterns into one regexp with alternation, e.g. \"@^(this|that)@\" instead of adding a third array element.","Remove empty strings or null placeholders left over from drafting."],"exampleFix":"// before\n[\"@^title$@\", \"@^urgent@\", \"@^asap@\"]\n\n// after\n[\"@^(title|summary)$@\", \"@(urgent|asap)@\"]","handlingStrategy":"validation","validationCode":"$json = phutil_json_decode($value); // assume decode succeeded\nif (!is_array($json) || count($json) !== 2) {\n  return pht('Regexp pair must contain exactly two patterns.');\n}","typeGuard":"function isHeraldRegexpPair($decoded) {\n  return is_array($decoded) && count($decoded) === 2\n    && isset($decoded[0]) && isset($decoded[1]);\n}","tryCatchPattern":"try {\n  $editor->save();\n} catch (HeraldInvalidConditionException $ex) {\n  // check the message: 'exactly two elements' means fix the array shape,\n  // not the regexes themselves\n}","preventionTips":["Build pair values from a two-element template so the length is structural, not manual.","Collapse multiple patterns into one alternation regexp instead of adding array elements."],"tags":["herald","phabricator","php","json","validation","array-length","rule-engine"],"backgroundTag":"json-schema-validation","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}