We've had cases (like with other posts) where we've received "Invalid Course Module ID". This has been seen when trying to delete a user, submit a quiz attempt, or even the task "Updating overdue attempts" executing.
We've noticed that when deleting a course module, if there is any issue while the delete process is taking place, it fails and stops executing the rest of the delete functions. This means that it didn't complete the delete process, so you could sit with records in various tables that exist that are not supposed to be there anymore. What then happens is that because the course module is partially delete, it is still visible in the course_modules table but it doesn't show up in the cache anymore, then the error happens at the get_cm function.
Using examples - looking at the code, we can see that for a quiz (code reference here) and an assignment (code reference here), it just executes the deletes one-by-one. However, if there is an API call to delete multiple users (code reference here), it wraps that in a transaction so that it can rollback if there's some sort of failure (code reference here).
If it starts executing the delete functions one-by-one and fails before it can execute all of them, is there a way to find the "broken" quizzes or assignments so that they can be cleaned up afterwards or at least make it noticeable by Moodle so that we can try the delete again from the frontend?