pallets/flask · error · TypeError

is an instance, not a class. Handlers can only be…

Error message

{exc_class!r} is an instance, not a class. Handlers can only be registered for Exception classes or HTTP error codes.

What it means

_register_error_handler expects a class (or an int code). If the value passes the int check but isinstance(value, Exception) is True, it means the user passed an instance rather than a class, so Flask raises TypeError. Handlers must be registered against exception classes, not instances of them.

Solutions

  1. Pass the class itself, not an instance: errorhandler(ValueError) not errorhandler(ValueError()).
  2. If the value comes from a variable, ensure it is a type: use `exc if isinstance(exc, type) else type(exc)`.
  3. Double-check that you are not accidentally calling the constructor.

Example fix

// before
@app.errorhandler(MyException('msg'))
def handle(e): ...

// after
@app.errorhandler(MyException)
def handle(e): ...
Defensive patterns

Strategy: type-guard

Validate before calling

def to_error_class(exc):
    if isinstance(exc, type) and issubclass(exc, Exception):
        return exc
    if isinstance(exc, Exception):
        return type(exc)
    raise TypeError('pass an Exception class, not an instance')

Type guard

def is_exception_class(obj) -> bool:
    return isinstance(obj, type) and issubclass(obj, Exception)

Prevention

When it happens

Trigger: @app.errorhandler(ValueError('x')); app.register_error_handler(SomeException()); passing an instantiated exception object instead of the class.

Common situations: Mistakenly instantiating the exception; refactoring that replaced a class reference with a constructed instance; dynamic code that builds exception objects for registration.

Related errors


AI-assisted analysis of pallets/flask@3596b1ab61 (2026-08-11). Data as JSON: /api/errors/77af1ea60403b000. Report an issue: GitHub.

Appendix: source

Thrown at src/flask/sansio/scaffold.py:682

        :param exc_class_or_code: Any exception class, or an HTTP status
            code as an integer.
        """
        exc_class: type[Exception]

        if isinstance(exc_class_or_code, int):
            try:
                exc_class = default_exceptions[exc_class_or_code]
            except KeyError:
                raise ValueError(
                    f"'{exc_class_or_code}' is not a recognized HTTP"
                    " error code. Use a subclass of HTTPException with"
                    " that code instead."
                ) from None
        else:
            exc_class = exc_class_or_code

        if isinstance(exc_class, Exception):
            raise TypeError(
                f"{exc_class!r} is an instance, not a class. Handlers"
                " can only be registered for Exception classes or HTTP"
                " error codes."
            )

        if not issubclass(exc_class, Exception):
            raise ValueError(
                f"'{exc_class.__name__}' is not a subclass of Exception."
                " Handlers can only be registered for Exception classes"
                " or HTTP error codes."
            )

        if issubclass(exc_class, HTTPException):
            return exc_class, exc_class.code
        else:
            return exc_class, None

View on GitHub (pinned to 3596b1ab61)