Environment Variables That Exist in Your Shell But Not in Cron
One of the most confusing debugging sessions you will ever have: a script that works perfectly when you run it manually but fails silently in cron. Nine times out of ten, the answer is environment variables.
Why This Happens
When you open a terminal, your shell loads profile files — .bashrc, .zshrc, .profile — that set up PATH, custom variables, API keys, and other configuration. Cron does not load any of these. It runs with a minimal environment that typically only includes HOME, LOGNAME, and a very basic PATH.
So when your script calls python3, cron might not find it because /usr/local/bin is not in cron's PATH. When your script reads DATABASE_URL from the environment, it gets nothing because that variable was set in .bashrc.
Common Symptoms
- Script runs fine manually, fails in cron with "command not found"
- Database connections fail because connection strings are missing
- API calls return authentication errors because API keys are not set
- File paths that use ~ or /Users/vitalijgolubenko behave differently
Fixes That Actually Work
The most reliable approach: use absolute paths for everything. Instead of python3, use /usr/local/bin/python3. Instead of relying on environment variables, read configuration from a file.
If you must use environment variables, source your profile at the start of the cron script. Something like source /home/user/.bashrc before the actual command. It is not elegant, but it works.
Another option: define the variables directly in the crontab. You can set PATH and other variables at the top of the crontab file, and they will apply to all jobs below them.
Prevention
Before adding any job to cron, test it with env -i to simulate a clean environment. If it works with no environment variables loaded, it will work in cron. If it does not, you know exactly what to fix.