{"record":{"id":"be424c7d64acc5bb","repo":"pytest-dev/pytest","slug":"only-exceptiongroup-exception-or-baseexception","errorCode":null,"errorMessage":"Only `ExceptionGroup[Exception]` or `BaseExceptionGroup[BaseException]` are accepted as generic types but got `{exc}`. As `raises` will catch all instances of the specified group regardless of the generic argument specific nested exceptions has to be checked with `RaisesGroup`.","messagePattern":"Only `ExceptionGroup\\[Exception\\]` or `BaseExceptionGroup\\[BaseException\\]` are accepted as generic types but got `(.+?)`\\. As `raises` will catch all instances of the specified group regardless of the generic argument specific nested exceptions has to be checked with `RaisesGroup`\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/raises.py","lineNumber":441,"sourceCode":"            if not issubclass(exc, Exception):\n                self.is_baseexception = True\n            return exc\n        # because RaisesGroup does not support variable number of exceptions there's\n        # still a use for RaisesExc(ExceptionGroup[Exception]).\n        origin_exc: type[BaseException] | None = get_origin(exc)\n        if origin_exc and issubclass(origin_exc, BaseExceptionGroup):\n            exc_type = get_args(exc)[0]\n            if (\n                issubclass(origin_exc, ExceptionGroup) and exc_type in (Exception, Any)\n            ) or (\n                issubclass(origin_exc, BaseExceptionGroup)\n                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","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/pytest-dev/pytest/blob/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/raises.py#L423-L459","documentation":"Raised by RaisesExc._parse_exc when a parameterized exception group is passed to pytest.raises (or RaisesExc) with a generic argument that is not exactly Exception, BaseException, or Any. pytest intentionally rejects constrained generics like ExceptionGroup[ValueError] because pytest.raises catches the whole group regardless of the type argument, so the nested type would be silently ignored and produce misleading tests. Use RaisesGroup to assert on nested exception types.","triggerScenarios":"Calling pytest.raises(ExceptionGroup[ValueError]), pytest.raises(BaseExceptionGroup[KeyboardInterrupt]), or RaisesExc(ExceptionGroup[KeyError]) — any BaseExceptionGroup subclass parameterized with a concrete non-Any, non-base exception type. The branch fires after get_origin(exc) returns a BaseExceptionGroup subclass and get_args(exc)[0] fails the Exception/BaseException/Any membership check.","commonSituations":"Developers new to Python 3.11 exception groups who try to assert 'a group containing ValueError' with the natural-looking raises(ExceptionGroup[ValueError]) syntax. Migrating from raises(ValueError) to group-based assertions and assuming the type parameter expresses the inner expectation.","solutions":["Replace pytest.raises(ExceptionGroup[ValueError]) with pytest.raises(ExceptionGroup) wrapped in or followed by a RaisesGroup(ValueError) assertion to inspect nested exceptions.","Use RaisesGroup(ValueError) directly as the raises argument to match a group whose leaf is ValueError.","If you truly want to catch any ExceptionGroup, pass ExceptionGroup (bare) or ExceptionGroup[Any]."],"exampleFix":"// before\nwith pytest.raises(ExceptionGroup[ValueError]):\n    ...\n// after\nwith pytest.raises(RaisesGroup(ValueError)):\n    ...\n// or for the outer group catch plus inner check:\nwith pytest.raises(ExceptionGroup) as eg:\n    ...\nassert RaisesGroup(ValueError).matches(eg.value)","handlingStrategy":"validation","validationCode":"import typing\norigin = typing.get_origin(exc)\nif origin is not None and issubclass(origin, BaseExceptionGroup):\n    arg = typing.get_args(exc)[0]\n    assert arg in (Exception, BaseException, typing.Any), (\n        f'pytest.raises cannot constrain {origin.__name__}[{arg.__name__}]; '\n        'use RaisesGroup for nested-type matching'\n    )","typeGuard":"def is_valid_raises_group_generic(exc) -> bool:\n    import typing\n    origin = typing.get_origin(exc)\n    if origin is None or not issubclass(origin, BaseExceptionGroup):\n        return True\n    arg = typing.get_args(exc)[0]\n    return arg in (Exception, BaseException, typing.Any)","tryCatchPattern":null,"preventionTips":["Treat pytest.raises group generics as catch-all; use RaisesGroup for nested-type assertions.","Add a lint rule or pre-commit check flagging raises(ExceptionGroup[<concrete>]).","Document the convention in your test helpers."],"tags":["pytest","exception-group","raises","type-argument","validation"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}