A script that succeeds interactively but fails in cron may be running from another directory. Record the first traceback, the absolute interpreter path and the current working directory. Inspect selected environment values rather than dumping everything, which may expose tokens or database passwords.
Three runs with the interpreter held constant
Using Python 3.12.3, a temporary application directory contained read.py and input.txt. Reading relative input.txt returned exit code 0 when launched there, but FileNotFoundError and exit code 1 from the parent directory. Resolving the path from the script file returned 0 from the parent as well. No packages or permissions changed.
from pathlib import Path
import sys
print("interpreter:", sys.executable)
print("cwd:", Path.cwd())
data_file = Path(__file__).resolve().parent / "input.txt"
print(data_file.read_text())
This example fits a static input shipped beside a script. Deployment configuration and writable data may instead need an explicit external path argument. Compare the relative-path behavior with Path.cwd. Only print test-file contents that contain no secrets.
Differences that remain after the CWD is correct
For ModuleNotFoundError, compare cron’s interpreter with the virtual environment used interactively. For Permission denied, inspect access under the scheduled account. For network failures, inspect proxy and CA configuration separately. One PATH adjustment does not explain all three problems.
When updating the real schedule, specify absolute paths for the interpreter, script and configuration, plus a log destination. Run once under the same identity, then inspect the next scheduled result. This fixture reproduces only a CWD difference; it does not validate backup completeness or cron execution.