pytest-dev/pytest · error · ValueError
Expected an exception type or a tuple of exception types, bu
Error message
Expected an exception type or a tuple of exception types, but got `{expected_exception!r}`. Raising exceptions is already understood as failing the test, so you don't need any special code to say 'this should never raise an exception'. What it means
Raised by the function-call form of pytest.raises when the first positional argument (expected_exception) is falsy. pytest already treats any uncaught exception as a test failure, so there is no 'assert it does not raise' mode via raises. Passing None/empty here is a misuse of the API.
Source
Thrown at src/_pytest/raises.py:269
frame) alive until the next cyclic garbage collection run.
More detailed information can be found in the official Python
documentation for :ref:`the try statement <python:try>`.
"""
__tracebackhide__ = True
if func is None and not args:
if set(kwargs) - {"match", "check", "expected_exception"}:
msg = "Unexpected keyword arguments passed to pytest.raises: "
msg += ", ".join(sorted(kwargs))
msg += "\nUse context-manager form instead?"
raise TypeError(msg)
if expected_exception is None:
return RaisesExc(**kwargs)
return RaisesExc(expected_exception, **kwargs)
if not expected_exception:
raise ValueError(
f"Expected an exception type or a tuple of exception types, but got `{expected_exception!r}`. "
f"Raising exceptions is already understood as failing the test, so you don't need "
f"any special code to say 'this should never raise an exception'."
)
if not callable(func):
raise TypeError(f"{func!r} object (type: {type(func)}) must be callable")
with RaisesExc(expected_exception) as excinfo:
func(*args, **kwargs)
try:
return excinfo
finally:
del excinfo
# note: RaisesExc/RaisesGroup uses fail() internally, so this alias
# indicates (to [internal] plugins?) that `pytest.raises` will
# raise `_pytest.outcomes.Failed`, where
# `outcomes.Failed is outcomes.fail.Exception is raises.Exception`View on GitHub (pinned to 98b357f69e)
Solutions
- Remove the pytest.raises wrapper entirely — a test that should not raise simply runs the code directly; an unexpected exception already fails the test.
- If you conditionally expect no exception, branch on the parametrized value and only wrap when an exception type is present.
- If you need an explicit 'did not raise' assertion, use try/except around the call with pytest.fail('unexpectedly raised') in the except block.
- Audit the parametrize table / variable source feeding expected_exception to ensure it is never None or empty when reaching raises.
Example fix
// before
pytest.raises(maybe_none_exc, my_func)
// after
if maybe_none_exc is not None:
with pytest.raises(maybe_none_exc):
my_func()
else:
my_func() Defensive patterns
Strategy: validation
Validate before calling
if not expected_exception:
raise ValueError('expected_exception must be a non-empty exception type or tuple')
# only then:
pytest.raises(expected_exception, func) Type guard
def is_valid_expected(exc) -> bool:
return bool(exc) and (
isinstance(exc, type) and issubclass(exc, BaseException)
or isinstance(exc, tuple) and all(isinstance(e, type) and issubclass(e, BaseException) for e in exc)
) Prevention
- Never pass None as expected_exception to the function-call form; if 'no exception' is the intent, drop the wrapper.
- When parametrizing exception types, include only real exception classes and handle the 'no-expect' case outside raises.
- Run a quick truthiness + isinstance check on dynamic expected_exception values before calling raises.
When it happens
Trigger: Calling pytest.raises(None, my_func), pytest.raises((), my_func), or pytest.raises(0, my_func) — i.e. the function-call form (raises(exc, func)) where exc evaluates to a falsy value. Hits the branch at raises.py:268 (`if not expected_exception:`).
Common situations: A parametrized variable intended to hold an exception class is None for some parameter combo; a refactor leaves a stale variable; or a developer misunderstands raises as a 'should not raise' assertion.
Related errors
- {func!r} object (type: {type(func)}) must be callable
- Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[Base
- Expected {expected}, but got {exc.__name__!r}
- Expected {expected}, but got an exception instance: {type(ex
- You must specify at least one parameter to match on.
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/d1b5b239cd32d4d1.json.
Report an issue: GitHub.