Crontab Traps: Unescaped %, Minimal PATH and Silent Output
The crontab checker reads every line for the mistakes that cron does not report. These are the ones it looks for.
An unescaped % becomes a newline
In a crontab command, the first unescaped % is turned into a newline and everything after it becomes the command's standard input. So:
30 2 * * * tar czf /tmp/$(date +%F).tgz /data
runs tar czf /tmp/$(date + with the rest as input, and the job fails with a syntax error, usually unseen. Write date +\%F. The checker flags any % not preceded by a backslash.
Minimal environment
Cron starts jobs with a small environment: a short PATH (commonly /usr/bin:/bin), no login profile, HOME and SHELL set by the daemon. A script that relies on /usr/local/bin or on nvm, pyenv or a virtualenv works in your terminal and fails in cron with "command not found". Use absolute paths, or set PATH= at the top of the crontab. The checker notes a command whose first word has no path, and notes when you did set PATH.
Output goes to mail, or nowhere
Anything a job prints is mailed to MAILTO (the user by default). On a host with no mail system that means it is lost; with MAILTO="" it is discarded on purpose. Redirect explicitly, > /var/log/job.log 2>&1, or pipe to logger. The checker flags a job with no redirection and an empty MAILTO.
Overlapping runs
If a run takes longer than the interval, the next starts anyway. Wrap work in flock -n /tmp/job.lock command so a slow run cannot stack against the next one.
Not covered
The checker does not read /etc/cron.d files, which have a user column after the schedule, and it cannot see file ownership or permissions.