{"record":{"id":"b4e6aa2629298b3d","repo":"sebastianbergmann/phpunit","slug":"invalid-expected-exception-message-regular-express","errorCode":null,"errorMessage":"Invalid expected exception message regular expression given: %s","messagePattern":"Invalid expected exception message regular expression given: (.+?)","errorType":"exception","errorClass":"PHPUnit\\Framework\\Exception","httpStatus":null,"severity":"error","filePath":"src/Framework/Constraint/Exception/ExceptionMessageMatchesRegularExpression.php","lineNumber":53,"sourceCode":"    }\n\n    /**\n     * Evaluates the constraint for parameter $other. Returns true if the\n     * constraint is met, false otherwise.\n     *\n     * @throws \\PHPUnit\\Framework\\Exception\n     * @throws Exception\n     */\n    protected function matches(mixed $other): bool\n    {\n        if (!is_string($other)) {\n            return false;\n        }\n\n        $match = @preg_match($this->regularExpression, $other);\n\n        if ($match === false) {\n            throw new \\PHPUnit\\Framework\\Exception(\n                sprintf(\n                    'Invalid expected exception message regular expression given: %s',\n                    $this->regularExpression,\n                ),\n            );\n        }\n\n        return $match === 1;\n    }\n\n    /**\n     * Returns the description of the failure.\n     *\n     * The beginning of failure messages is \"Failed asserting that\" in most\n     * cases. This method should return the second part of that sentence.\n     */\n    protected function failureDescription(mixed $other): string\n    {","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Framework/Constraint/Exception/ExceptionMessageMatchesRegularExpression.php#L35-L71","documentation":"The ExceptionMessageMatchesRegularExpression constraint backs expectExceptionMessageMatches(): it runs @preg_match($this->regularExpression, $message). When PCRE rejects the pattern (preg_match returns false rather than 0 or 1), it throws Framework\\Exception('Invalid expected exception message regular expression given: <pattern>'). The failure is in the pattern itself, not in the tested code.","triggerScenarios":"Calling $this->expectExceptionMessageMatches($pattern) with a malformed PCRE pattern: missing delimiters ('SomeMessage' with no /.../), unbalanced delimiters, an unknown trailing modifier, or invalid UTF-8 sequences with the u modifier.","commonSituations":"Upgrading from PHPUnit 9's expectExceptionMessageRegExp where delimiter habits differed; copy-pasting substrings instead of full patterns; patterns assembled dynamically where a fragment is empty or malformed.","solutions":["Make the pattern a valid PCRE expression with matching delimiters, e.g. '/timeout after \\d+ seconds/i'","If you only need a literal check, use expectExceptionMessage($substring) instead — no regex involved","Test dynamic patterns before use: if (@preg_match($pattern, '') === false) { /* fix pattern */ }","Simplify the regex; a long anchored pattern is more likely to contain a syntax slip than a short one"],"exampleFix":"// before\n$this->expectException(TimeoutException::class);\n$this->expectExceptionMessageMatches('timeout after \\d+ seconds'); // no delimiters\n\n// after\n$this->expectException(TimeoutException::class);\n$this->expectExceptionMessageMatches('/timeout after \\d+ seconds/i');","handlingStrategy":"validation","validationCode":"$pattern = '/timeout after \\d+ seconds/i';\nif (@preg_match($pattern, '') === false) {\n    throw new InvalidArgumentException(\"Invalid regex: {$pattern}\");\n}","typeGuard":"static function isValidPcrePattern(string $pattern): bool\n{\n    return @preg_match($pattern, '') !== false;\n}","tryCatchPattern":"try {\n    $this->expectExceptionMessageMatches($pattern);\n} catch (\\PHPUnit\\Framework\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Invalid expected exception message regular expression')) {\n        // fix the pattern (delimiters/modifiers) before re-running\n    }\n    throw $e;\n}","preventionTips":["Always include delimiters and keep modifiers to the well-known set (i u i? m s x) — exactly one leading delimiter pair","Prefer expectExceptionMessage($substring) for literal checks; reserve regex for real patterns","Add a lint step for test helpers that build regexes from variables"],"tags":["phpunit","regex","pcre","assertion","exception-expectation"],"backgroundTag":"invalid-regex","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}