An error while handling an error is certainly a possibility, but this is already correctly implemented in RequestCycle.step() using the handlingException flag. Handling fatal errors can never be more than a "best effort" implementation, as you have already pointed out.
My point is that if there is a method that handles fatal errors, it should handle ALL fatal errors, not just RuntimeException.
For example, StackOverflowError is usually caused by unchecked recursion, certainly a programming mistake. In such a case, I want to log this error just as I log a SQL error from the persistence provider, informing the maintenance crew for the application, and then I want to show the user the usual error page. There is no point in informing the system administrators because the Servlet container reported an unhandled exception, or showing a generic error page for the Servlet container instead of the applications error page.
AssertionError is pretty much the same - these also occur in production when they are thrown explicitly, which is not uncommon (a grep over the JDK sources for 6u21 shows 293 occurrences).
Thus, I propose that either RequestCycle.step() is not declared final, or that Throwable is caught and handled pretty much like RuntimeException now, possibly re-throwing it in an override-able method.
I do understand that you do not want to catch Throwable because you cannot simply re-throw it, but this is also not uncommon (find -name *.java | xargs grep 'catch *( *Throwable' | wc -l over the same JDK 6u21 sources finds 330 occurrences), and there can be just two cases of unchecked exceptions anyway: Error or RuntimeException. Thus, the handling can be exactly like in java.io.ObjectStreamClass.java:2110 for example - test for Error, then RuntimeException - it must be one or the other.