pytest-dev/pytest · error · TypeError
Expected , but got an exception instance
Error message
Expected {expected}, but got an exception instance: {type(exc).__name__} What it means
Raised by RaisesExc._parse_exc when an exception INSTANCE is passed where a TYPE is expected. pytest.raises/RaisesExc accept classes (or group generics), not instances like ValueError('x'). The TypeError reports the actual instance type so the caller sees the mismatch.
Solutions
- Pass the class: pytest.raises(ValueError) instead of pytest.raises(ValueError('boom')).
- If asserting on message, use the match= argument: pytest.raises(ValueError, match='boom').
- When the value comes from excinfo, use type(excinfo.value).
Example fix
// before
with pytest.raises(ValueError('boom')):
...
// after
with pytest.raises(ValueError, match='boom'):
... Defensive patterns
Strategy: type-guard
Validate before calling
assert not isinstance(exc, BaseException), f'pass the exception class, not an instance: {type(exc).__name__}' Type guard
def is_exception_class_not_instance(exc) -> bool:
return isinstance(exc, type) and not isinstance(exc, BaseException) Prevention
- Pass classes (ValueError), not instances (ValueError('x')), to raises.
- Use match= to assert on the message rather than constructing an instance.
- When forwarding from excinfo, use type(excinfo.value).
When it happens
Trigger: pytest.raises(ValueError('boom')), RaisesExc(RuntimeError('x')), or passing excinfo.value (an instance) instead of type(excinfo.value). Fires on the isinstance(exc, BaseException) branch after the type branch.
Common situations: Copy-paste from a raise ValueError('x') line into raises(...); passing a caught exception instance through a variable; beginners assuming raises mirrors raise syntax.
Related errors
- Expected , but got
- You must specify at least one parameter to match on.
- `allow_unwrapped=True` bypasses the `match` and `check`…
- `allow_unwrapped=True` has no effect when expecting a…
- approx() is not supported in a boolean context. Did you…
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/8a3ca6facf5608bd.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/raises.py:453
and exc_type in (BaseException, Any)
):
if not issubclass(origin_exc, ExceptionGroup):
self.is_baseexception = True
return cast(type[BaseExcT_1], origin_exc)
else:
raise ValueError(
f"Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[BaseException]` "
f"are accepted as generic types but got `{exc}`. "
f"As `raises` will catch all instances of the specified group regardless of the "
f"generic argument specific nested exceptions has to be checked "
f"with `RaisesGroup`."
)
# unclear if the Type/ValueError distinction is even helpful here
msg = f"Expected {expected}, but got "
if isinstance(exc, type): # type: ignore[unreachable]
raise ValueError(msg + f"{exc.__name__!r}")
if isinstance(exc, BaseException): # type: ignore[unreachable]
raise TypeError(msg + f"an exception instance: {type(exc).__name__}")
raise TypeError(msg + repr(type(exc).__name__))
@property
def fail_reason(self) -> str | None:
"""Set after a call to :meth:`matches` to give a human-readable reason for why the match failed.
When used as a context manager the string will be printed as the reason for the
test failing."""
return self._fail_reason
def _check_check(
self: AbstractRaises[BaseExcT_1],
exception: BaseExcT_1,
) -> bool:
if self.check is None:
return True
if self.check(exception):
return TrueView on GitHub (pinned to 0d6fbdeffa)