{"id":"8a3ca6facf5608bd","repo":"pytest-dev/pytest","slug":"expected-expected-but-got-an-exception-instance","errorCode":null,"errorMessage":"Expected {expected}, but got an exception instance: {type(exc).__name__}","messagePattern":"Expected (.+?), but got an exception instance: (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/raises.py","lineNumber":453,"sourceCode":"                and exc_type in (BaseException, Any)\n            ):\n                if not issubclass(origin_exc, ExceptionGroup):\n                    self.is_baseexception = True\n                return cast(type[BaseExcT_1], origin_exc)\n            else:\n                raise ValueError(\n                    f\"Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[BaseException]` \"\n                    f\"are accepted as generic types but got `{exc}`. \"\n                    f\"As `raises` will catch all instances of the specified group regardless of the \"\n                    f\"generic argument specific nested exceptions has to be checked \"\n                    f\"with `RaisesGroup`.\"\n                )\n        # unclear if the Type/ValueError distinction is even helpful here\n        msg = f\"Expected {expected}, but got \"\n        if isinstance(exc, type):  # type: ignore[unreachable]\n            raise ValueError(msg + f\"{exc.__name__!r}\")\n        if isinstance(exc, BaseException):  # type: ignore[unreachable]\n            raise TypeError(msg + f\"an exception instance: {type(exc).__name__}\")\n        raise TypeError(msg + repr(type(exc).__name__))\n\n    @property\n    def fail_reason(self) -> str | None:\n        \"\"\"Set after a call to :meth:`matches` to give a human-readable reason for why the match failed.\n        When used as a context manager the string will be printed as the reason for the\n        test failing.\"\"\"\n        return self._fail_reason\n\n    def _check_check(\n        self: AbstractRaises[BaseExcT_1],\n        exception: BaseExcT_1,\n    ) -> bool:\n        if self.check is None:\n            return True\n\n        if self.check(exception):\n            return True","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/raises.py#L435-L471","documentation":"Raised when an exception INSTANCE is passed where an exception TYPE was expected. raises/RaisesExc want the class, not a constructed instance.","triggerScenarios":"Calling pytest.raises(ValueError('oops')) or RaisesExc(ValueError()). Hits raises.py:453 when isinstance(exc, BaseException) is True (i.e. it is an instance, not a type).","commonSituations":"Developer constructs the exception to communicate the expected message, then passes the instance instead of the class; copy-paste from a raise statement.","solutions":["Pass the exception class (ValueError), not an instance (ValueError()).","If you intended to also match the message, pass the class plus match='oops'.","If you have an instance variable, pass type(instance) instead of the instance."],"exampleFix":"// before\npytest.raises(ValueError('oops'))\n// after\npytest.raises(ValueError, match='oops')","handlingStrategy":"type-guard","validationCode":"if isinstance(exc, BaseException):\n    raise TypeError('pass the exception class, not an instance')\npytest.raises(exc)","typeGuard":"def is_exception_class(exc) -> TypeGuard[type[BaseException]]:\n    return isinstance(exc, type) and issubclass(exc, BaseException)","tryCatchPattern":null,"preventionTips":["Pass the class (ValueError), never an instance (ValueError()).","If you only have an instance, pass type(instance).","To also match the message, use match= rather than constructing the instance."],"tags":["pytest","raises","validation","type-check"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}