I remember noticing this long ago, but it seems I never reported it as an issue.
The way the MAIN function is handled in the runtime means we catch and handle X::ParameterMismatch exceptions that get thrown as part of MAIN parameter handling. But... we also wrongly catch and handle other thrown X::ParameterMismatch exceptions that get thrown as part of running MAIN. This is wrong.
The solution seems involve separating out parameter binding from actually making the call. So that we can put the CATCH on the parameter binding only.