{"record":{"id":"d1b5b239cd32d4d1","repo":"pytest-dev/pytest","slug":"expected-an-exception-type-or-a-tuple-of-exception","errorCode":null,"errorMessage":"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'.","messagePattern":"Expected an exception type or a tuple of exception types, but got `(.+?)`\\. 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'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/raises.py","lineNumber":269,"sourceCode":"        frame) alive until the next cyclic garbage collection run.\n        More detailed information can be found in the official Python\n        documentation for :ref:`the try statement <python:try>`.\n    \"\"\"\n    __tracebackhide__ = True\n\n    if func is None and not args:\n        if set(kwargs) - {\"match\", \"check\", \"expected_exception\"}:\n            msg = \"Unexpected keyword arguments passed to pytest.raises: \"\n            msg += \", \".join(sorted(kwargs))\n            msg += \"\\nUse context-manager form instead?\"\n            raise TypeError(msg)\n\n        if expected_exception is None:\n            return RaisesExc(**kwargs)\n        return RaisesExc(expected_exception, **kwargs)\n\n    if not expected_exception:\n        raise ValueError(\n            f\"Expected an exception type or a tuple of exception types, but got `{expected_exception!r}`. \"\n            f\"Raising exceptions is already understood as failing the test, so you don't need \"\n            f\"any special code to say 'this should never raise an exception'.\"\n        )\n    if not callable(func):\n        raise TypeError(f\"{func!r} object (type: {type(func)}) must be callable\")\n    with RaisesExc(expected_exception) as excinfo:\n        func(*args, **kwargs)\n    try:\n        return excinfo\n    finally:\n        del excinfo\n\n\n# note: RaisesExc/RaisesGroup uses fail() internally, so this alias\n#  indicates (to [internal] plugins?) that `pytest.raises` will\n#  raise `_pytest.outcomes.Failed`, where\n#  `outcomes.Failed is outcomes.fail.Exception is raises.Exception`","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/pytest-dev/pytest/blob/0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc/src/_pytest/raises.py#L251-L287","documentation":"Thrown by pytest.raises() in the function-call form (expected_exception + func) when expected_exception is falsy: None, False, 0, empty tuple, etc. pytest can't assert that 'no exception' occurs this way since test failure already implies that.","triggerScenarios":"Calling pytest.raises(None, func) or pytest.raises((), func); a variable holding an exception type that resolved to None; pytest.raises(False, some_callable).","commonSituations":"Conditionally computing an expected exception that ended up None; refactoring where the exception type was moved; misunderstanding that pytest.raises is for asserting exceptions ARE raised.","solutions":["Pass a concrete exception class or tuple of classes.","If you expect no exception, just call the function directly (test fails if it raises).","Guard with `if expected_exception is not None:` before calling pytest.raises."],"exampleFix":"// before\nexc = get_exc_type()  # may return None\npytest.raises(exc, func)\n// after\nexc = get_exc_type()\nassert exc is not None, \"expected exception type required\"\npytest.raises(exc, func)","handlingStrategy":"validation","validationCode":"if not expected_exception:\n    raise ValueError('pytest.raises needs a real exception type, not a falsy value')\npytest.raises(expected_exception, func)","typeGuard":"def is_exception_type(e: object) -> bool:\n    return isinstance(e, type) and issubclass(e, BaseException)","tryCatchPattern":null,"preventionTips":["Pass a concrete exception class or tuple of classes.","If you expect no exception, call the function directly.","Guard dynamically-computed exception types with an assert before passing."],"tags":["raises","expected-exception","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"0d6fbdeffa57c796123f62f81f7dd370d9b7ecdc","analyzedAt":"2026-08-11T20:52:36.969Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}