{"id":"ec0fcfbec950d29a","repo":"pytest-dev/pytest","slug":"allow-unwrapped-true-bypasses-the-match-and-c","errorCode":null,"errorMessage":"`allow_unwrapped=True` bypasses the `match` and `check` parameters if the exception is unwrapped. If you intended to match/check the exception you should use a `RaisesExc` object. If you want to match/check the exceptiongroup when the exception *is* wrapped you need to do e.g. `if isinstance(exc.value, ExceptionGroup): assert RaisesGroup(...).matches(exc.value)` afterwards.","messagePattern":"`allow_unwrapped=True` bypasses the `match` and `check` parameters if the exception is unwrapped\\. If you intended to match/check the exception you should use a `RaisesExc` object\\. If you want to match/check the exceptiongroup when the exception \\*is\\* wrapped you need to do e\\.g\\. `if isinstance\\(exc\\.value, ExceptionGroup\\): assert RaisesGroup\\(\\.\\.\\.\\)\\.matches\\(exc\\.value\\)` afterwards\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/raises.py","lineNumber":984,"sourceCode":"        self.allow_unwrapped = allow_unwrapped\n        self.flatten_subgroups: bool = flatten_subgroups\n        self.is_baseexception = False\n\n        if allow_unwrapped and other_exceptions:\n            raise ValueError(\n                \"You cannot specify multiple exceptions with `allow_unwrapped=True.`\"\n                \" If you want to match one of multiple possible exceptions you should\"\n                \" use a `RaisesExc`.\"\n                \" E.g. `RaisesExc(check=lambda e: isinstance(e, (...)))`\",\n            )\n        if allow_unwrapped and isinstance(expected_exception, RaisesGroup):\n            raise ValueError(\n                \"`allow_unwrapped=True` has no effect when expecting a `RaisesGroup`.\"\n                \" You might want it in the expected `RaisesGroup`, or\"\n                \" `flatten_subgroups=True` if you don't care about the structure.\",\n            )\n        if allow_unwrapped and (match is not None or check is not None):\n            raise ValueError(\n                \"`allow_unwrapped=True` bypasses the `match` and `check` parameters\"\n                \" if the exception is unwrapped. If you intended to match/check the\"\n                \" exception you should use a `RaisesExc` object. If you want to match/check\"\n                \" the exceptiongroup when the exception *is* wrapped you need to\"\n                \" do e.g. `if isinstance(exc.value, ExceptionGroup):\"\n                \" assert RaisesGroup(...).matches(exc.value)` afterwards.\",\n            )\n\n        self.expected_exceptions: tuple[\n            type[BaseExcT_co] | RaisesExc[BaseExcT_co] | RaisesGroup[BaseException], ...\n        ] = tuple(\n            self._parse_excgroup(e, \"a BaseException type, RaisesExc, or RaisesGroup\")\n            for e in (\n                expected_exception,\n                *other_exceptions,\n            )\n        )\n","sourceCodeStart":966,"sourceCodeEnd":1002,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/raises.py#L966-L1002","documentation":"allow_unwrapped=True bypasses match and check on the group because, when the exception is unwrapped (not in a group), there is no group object to run match/check against. Combining them is contradictory and silently drops the match/check intent.","triggerScenarios":"Calling RaisesGroup(ValueError, allow_unwrapped=True, match='foo') or RaisesGroup(ValueError, allow_unwrapped=True, check=fn). Hits raises.py:984.","commonSituations":"Developer wants to both tolerate an unwrapped exception and assert a group-level message/check; not realizing the unwrapped path skips those checks.","solutions":["Move match/check onto a RaisesExc for the inner exception: RaisesGroup(RaisesExc(ValueError, match='foo'), allow_unwrapped=True).","If you only care about the wrapped case, drop allow_unwrapped and keep match/check on the group.","To conditionally check the group when it IS wrapped, assert afterward: if isinstance(exc.value, ExceptionGroup): assert RaisesGroup(...).matches(exc.value)."],"exampleFix":"// before\nRaisesGroup(ValueError, allow_unwrapped=True, match='foo')\n// after\nRaisesGroup(RaisesExc(ValueError, match='foo'), allow_unwrapped=True)","handlingStrategy":"validation","validationCode":"if allow_unwrapped and (match is not None or check is not None):\n    raise ValueError('move match/check onto a RaisesExc, or drop allow_unwrapped')\nRaisesGroup(expected, allow_unwrapped=allow_unwrapped, match=match, check=check)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never combine allow_unwrapped with group-level match/check.","Push match/check into a RaisesExc for the inner exception instead.","If you need conditional group checks, assert manually after the context exits."],"tags":["pytest","raises-group","validation"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}