Cron Job Reports Success but Did Nothing
Short answer
A cron job can report success because the shell process exited with code 0, even when the useful work never happened. The script may have skipped every record, written only a header, used the wrong environment, swallowed an exception, or produced an artifact that looks fresh but contains no real data. A green cron status proves the process ended; it does not prove the job did its job.
Why this happens
- The script catches the error and keeps going. A broad
except,|| true, or ignored command failure can hide the real problem. - A pipeline masks the failing command.
export_data | gzip > report.csv.gzcan return the status of the last command while the exporter failed upstream. - Cron runs with a different environment. Missing
PATH, credentials, working directory, or virtualenv setup can make the job take a no-op path. - The input query returns zero rows. The script succeeds technically, but the empty result is abnormal for that job.
- The output file is created before data is written. Redirection or an early
touchcan leave a fresh file that contains nothing useful. - The wrong file is checked. Relative paths can make the script write to one location while the monitor checks another.
Minimum checks before trusting success
- Artifact exists at the expected absolute path.
- Artifact is fresh for this schedule, not just present from a prior run.
- Size is plausible compared with recent successful runs.
- Rows or records are above a floor that matches the job’s normal output.
- Header or schema matches what downstream consumers expect.
- Logs contain the expected completion marker with counts, not just “done.”
Safer shell pattern
set -euo pipefail
cd /absolute/project
./generate_report > reports/latest.csv.tmp
test -s reports/latest.csv.tmp
rows=$(wc -l < reports/latest.csv.tmp)
test "$rows" -ge 2
mv reports/latest.csv.tmp reports/latest.csv
This still is not a full business validation, but it removes the easiest false green: a script that exits cleanly while producing an empty or malformed artifact.
What to log
Log counts that describe the actual work:
input_rows=1240
output_rows=1238
output_path=/srv/reports/latest.csv
output_bytes=98144
finished_at=2026-07-27T09:00:03Z
A line like job complete is not enough. Counts give both humans and monitors something concrete to compare.
Where Night Watchman fits
Night Watchman watches the artifact after the job runs. It checks freshness, size, rows, shape, and recent history, then sends a small evidence dossier when the file looks wrong. It does not assume a successful process means successful work.
FAQ
Why did cron email me no error if the job did nothing?
Cron only reports process output and exit status. If the script hides errors, writes no stderr, or exits 0, cron has nothing useful to email.
Is checking for file existence enough?
No. A fresh 0-byte file, a header-only CSV, or a tiny backup file can all exist while still being useless.
Should I monitor logs or output files?
Both help. Logs explain what the script thinks happened; output files prove whether the expected artifact exists and looks plausible.
Related pages
- Backup job succeeded but the file is empty
- Script works manually but not in cron
- Exit code 0 is not a health check
Try Night Watchman
Install from the public repository:
curl -fsSL https://raw.githubusercontent.com/ssddee-dev/code-batman/main/install.sh | bash
cd ~/night-watchman
.venv/bin/python -m watchman.setup