Claude writes confident code. Your server doesn't care about confidence. This lesson teaches you the exact system to validate AI output before it wastes your time.
You asked Claude Code for a cron job to post to X. It gave you code in under 30 seconds. It looked clean. It failed silently at 9am and you had no idea why.
There are exactly 3 reasons this happens. Click each one:
AI isn't lying — it's writing for an ideal environment that doesn't exist on your machine. Every gap between "what Claude assumed" and "what your server actually has" is a failure waiting to happen.
python3 post.py in your terminal — works perfectly. You set up a cron job for the same script — fails every time. What's most likely wrong?Claude Code executes against a spec. If you don't give it one, it invents one — based on ideal conditions, not yours. A PRD is just a list of facts Claude can't guess.
A Forge-standard PRD answers 5 questions. Reveal each:
Cron uses the system Python, not yours. Run which python3 to get the full path — use that exact path in cron, not just python3. If you installed tweepy via pip, you're using a virtual environment and need the venv's Python path: which python3 will show it if the venv is active.
Keys go in a .env file, never in the code. Claude needs the absolute path to load it explicitly. But first — verify at developer.twitter.com that your X app has Read and Write permissions. The default is Read-only. A perfectly written script fails silently with the wrong permissions.
Without logs, failures are invisible. Use an absolute path: not ./logs/post.log — that's relative and cron won't find it. Use /home/joe/scripts/logs/post.log. Cron has no working directory to resolve relative paths from.
Cron uses 5-field syntax that's easy to get wrong. Tell Claude the schedule in plain English — "every day at 9am" — and it generates the correct expression. You don't need to know cron syntax.
Should it retry? Notify you? Log and exit? Claude will make a default decision — make sure it's your decision. The most useful option for beginners: log the error and exit cleanly so you can diagnose from the file.
/. Cron can't resolve ./, ~/, or relative paths — it has no working directory. Always use the full path from root../ means "current folder" — which doesn't exist in cron's context. ~/ is a shell shortcut cron doesn't expand. Only full absolute paths starting with / work reliably.The AI that wrote the code was primed to produce it. A second prompt — even to the same model — with critic framing produces different, more skeptical output. You need a critic, not a builder.
Opening a new chat means zero priming toward the code being good. It will find environment issues, missing error handling, and auth gaps the original window glossed over.
You are a code critic. NOT a code writer. This script runs via cron and posts to X/Twitter. Find every way this FAILS: 1. Will it work when cron runs it with no environment loaded? 2. Are ALL file paths absolute (start with /)? 3. Is the .env file loaded with an absolute path? 4. Is auth validated BEFORE attempting to post? 5. Does it log errors or crash silently? 6. Does it use the correct Python path for this setup? 7. What happens on failure? For each issue: exact line number and the fix. [PASTE CODE HERE]
.env file and are loaded via os.getenv()..env file — never in the script itself.Imagine running your store at night with no security cameras. Logging is the camera. Every time the script runs — success or failure — it writes a timestamped record you can read the next morning.
import logging
import sys
from dotenv import load_dotenv
# ABSOLUTE path to .env — not ./ or ~/
load_dotenv('/home/joe/scripts/.env')
# ABSOLUTE path to log file
logging.basicConfig(
filename='/home/joe/scripts/logs/post.log',
level=logging.DEBUG,
format='%(asctime)s | %(levelname)s | %(message)s'
)
logging.info("=== Script started ===")
try:
# YOUR CODE GOES HERE
logging.info("Post successful")
except Exception as e:
logging.error(f"FAILED: {e}")
sys.exit(1) # signals failure to cron
load_dotenv('.env') is a relative path. Cron has no working directory, so it can't find the file. The credentials never load, auth fails, and the script dies — but only after the logging setup, so you'd see an auth error in the log if you're lucky.load_dotenv('.env') is a relative path. Cron can't resolve it — no working directory means no relative paths ever work. The .env never loads, credentials don't exist, and the script fails at auth. Always use the full absolute path.Once logging is in place, every future failure becomes a one-line diagnosis. You stop debugging with your brain — you paste the log into Claude and get the fix. That's the real leverage here.
This single command runs your script the same way cron will — with no environment loaded. If it fails here but works in your terminal, you just found the cron gap before it went live.
Step 1: Find your exact Python path first. This is critical if you used pip to install tweepy:
which python3
Step 2: Run the simulation using that exact path:
# Standard Python (replace with your path from 'which python3') env -i /usr/bin/python3 /absolute/path/to/script.py # If you used pip / virtual environment: env -i /home/joe/myproject/venv/bin/python3 /absolute/path/to/script.py
pip install tweepy, you have a virtual environment. Using the wrong Python path in this test (or in your cron job) means Python can't find tweepy and the script crashes with ModuleNotFoundError. Use the output of which python3 while your venv is active.crontab -e doesn't fire your job, use launchd instead. Ask Claude: "Convert this cron schedule to a macOS launchd plist file" — it will generate the correct file and the commands to load it.When something breaks, most people describe the problem in English to Claude. Stop doing that. Paste the log. Paste the script. Claude diagnoses from actual error output far more accurately than from your interpretation of what you think happened.
Here is my error log. Here is the script. Tell me: 1. The exact line that failed 2. Why it failed 3. Give me the corrected script only — no explanation LOG: [paste log here] SCRIPT: [paste script here]
Every failure you process through the log→paste→fix loop makes the next one faster. You stop debugging with your brain — you debug with evidence. That's how diagnostic systems work in every professional field.
The Complete System — In Order
10 questions · Wrong answers reveal the correct one