pytest-dev/pytest · error · AssertionError
{fail_reason}
Error message
{fail_reason} What it means
The AssertionError surfaced when an exception WAS raised and its type matched, but it failed the match regex or the check predicate. The message is the dynamically-built fail_reason explaining exactly why the match failed (regex mismatch, check returned False, etc.).
Source
Thrown at src/_pytest/raises.py:711
) -> bool:
__tracebackhide__ = True
if exc_type is None:
if not self.expected_exceptions:
fail("DID NOT RAISE any exception")
if len(self.expected_exceptions) == 1:
fail(f"DID NOT RAISE {self.expected_exceptions[0].__name__}")
else:
names = ", ".join(x.__name__ for x in self.expected_exceptions)
fail(f"DID NOT RAISE any of ({names})")
assert self.excinfo is not None, (
"Internal error - should have been constructed in __enter__"
)
if not self.matches(exc_val):
if self._just_propagate:
return False
raise AssertionError(self._fail_reason) from None
# Cast to narrow the exception type now that it's verified....
# even though the TypeGuard in self.matches should be narrowing
exc_info = cast(
"tuple[type[BaseExcT_co_default], BaseExcT_co_default, types.TracebackType]",
(exc_type, exc_val, exc_tb),
)
self.excinfo.fill_unfilled(exc_info)
return True
@final
class RaisesGroup(AbstractRaises[BaseExceptionGroup[BaseExcT_co]]):
"""
.. versionadded:: 8.4
Contextmanager for checking for an expected :exc:`ExceptionGroup`.
This works similar to :func:`pytest.raises`, but allows for specifying the structure of an :exc:`ExceptionGroup`.View on GitHub (pinned to 98b357f69e)
Solutions
- Read the fail_reason — it shows the expected regex and the actual message; align the regex to reality.
- Use re.escape(literal_text) when matching literal strings that contain regex metacharacters.
- Debug the check predicate in isolation to confirm it returns True for the actual exception.
- Loosen or correct the match pattern to reflect the current exception message format.
Example fix
// before
with pytest.raises(ValueError, match='^foo$'):
raise ValueError('bar')
// after
with pytest.raises(ValueError, match='bar'):
raise ValueError('bar') Defensive patterns
Strategy: try-catch
Try / catch
try:
with pytest.raises(ValueError, match=pattern):
func()
except AssertionError as e:
# inspect e.args[0] for the fail_reason, then fix pattern or check
raise Prevention
- Use re.escape(literal_text) for match patterns containing regex metacharacters.
- Keep match patterns loose (substring search) unless you need full anchoring with ^...$.
- Unit-test check predicates in isolation against representative exception instances.
- Update match patterns whenever the exception message format changes in the code under test.
When it happens
Trigger: with pytest.raises(ValueError, match='foo'): raise ValueError('bar') — type matches but the regex does not. Or a check=lambda e: e.code==5 that returns False. Hits raises.py:711.
Common situations: Regex is too strict or wrong; expected message wording changed in the code under test; the check predicate has a logic bug; special regex characters in the expected literal text are not escaped.
Related errors
- Invalid regex {e.pattern!r}: {e}
- Expected an exception type or a tuple of exception types, bu
- {func!r} object (type: {type(func)}) must be callable
- Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[Base
- Expected {expected}, but got {exc.__name__!r}
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/951c302d74f09e9c.json.
Report an issue: GitHub.