Nevermind. Was looking at the wrong job. Ran the script provided by Daniel Beck and it printed out the name of the right job that had a null trigger in config.xml.
The configuration history plugin shows two changes yesterday, with 1 minute difference (see attachments).
Untitled spreadsheet - Sheet1 (1).pdf Untitled spreadsheet - Sheet2.pdf
The user says he was editing other jobs at that time but doesn't recall modifying this particular one. But even if he edited it by mistake, it's still not clear what caused Jenkins to save null triggers, as well as remove a bunch of other configuration options.
Even if we can't reproduce this issue in full details, can you guys add a check for a null trigger? It's REALLY bad that one job with messed up configuration file causes the whole system to intermittently skip some scheduled jobs. The issue should be isolated to one job.