{"id":"c907ba7c31bf9136","repo":"pallets/flask","slug":"exc-class-name-is-not-a-subclass-of-except","errorCode":null,"errorMessage":"'{exc_class.__name__}' is not a subclass of Exception. Handlers can only be registered for Exception classes or HTTP error codes.","messagePattern":"'(.+?)' is not a subclass of Exception\\. Handlers can only be registered for Exception classes or HTTP error codes\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/flask/sansio/scaffold.py","lineNumber":689,"sourceCode":"                exc_class = default_exceptions[exc_class_or_code]\n            except KeyError:\n                raise ValueError(\n                    f\"'{exc_class_or_code}' is not a recognized HTTP\"\n                    \" error code. Use a subclass of HTTPException with\"\n                    \" that code instead.\"\n                ) from None\n        else:\n            exc_class = exc_class_or_code\n\n        if isinstance(exc_class, Exception):\n            raise TypeError(\n                f\"{exc_class!r} is an instance, not a class. Handlers\"\n                \" can only be registered for Exception classes or HTTP\"\n                \" error codes.\"\n            )\n\n        if not issubclass(exc_class, Exception):\n            raise ValueError(\n                f\"'{exc_class.__name__}' is not a subclass of Exception.\"\n                \" Handlers can only be registered for Exception classes\"\n                \" or HTTP error codes.\"\n            )\n\n        if issubclass(exc_class, HTTPException):\n            return exc_class, exc_class.code\n        else:\n            return exc_class, None\n\n\ndef _endpoint_from_view_func(view_func: ft.RouteCallable) -> str:\n    \"\"\"Internal helper that returns the default endpoint for a given\n    function.  This always is the function name.\n    \"\"\"\n    assert view_func is not None, \"expected view func if endpoint is not provided.\"\n    return view_func.__name__\n","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/sansio/scaffold.py#L671-L707","documentation":"Flask validates that a registered handler key is actually an Exception subclass, because runtime matching walks the raised exception's class hierarchy. A non-exception class (or any non-int, non-exception object) can never match a raised exception, so registration fails fast with ValueError.","triggerScenarios":"@app.errorhandler(SomeClass) or register_error_handler where SomeClass does not inherit from Exception — e.g. a plain class, a BaseException-only subclass (KeyboardInterrupt-style custom), a string, or an enum member.","commonSituations":"Custom 'error' classes that forgot to inherit Exception; passing a status-code enum instead of an int; registering a Werkzeug Response class or a sentinel by mistake.","solutions":["Make the custom error class inherit from Exception (or a subclass like RuntimeError/HTTPException).","If you meant an HTTP status, pass the integer code (e.g. 404) instead of a class.","Check imports — ensure you're referencing the exception class, not a similarly named model or constant."],"exampleFix":"# before\nclass PaymentError: ...\n@app.errorhandler(PaymentError)\ndef handle(e): ...\n# after\nclass PaymentError(Exception): ...\n@app.errorhandler(PaymentError)\ndef handle(e): ...","handlingStrategy":"type-guard","validationCode":"import inspect\nassert inspect.isclass(exc) and issubclass(exc, Exception), f\"{exc!r} must subclass Exception\"","typeGuard":"import inspect\ndef is_exception_class(obj) -> bool:\n    return inspect.isclass(obj) and issubclass(obj, Exception)","tryCatchPattern":null,"preventionTips":["Derive custom error types from Exception (or HTTPException), never from object or BaseException-only mixins","Don't pass arbitrary classes (enums, dataclasses, sentinels) as handler keys","Validate plugin-provided handler keys with the type guard at registration time"],"tags":["flask","error-handling","exceptions"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}