Read Logs

🔴 Red sticky = I need help. Put it up the moment you are stuck — an instructor will come to you.

🟢 Green sticky = I have done 1–4 and am moving on to the bonus work, and I am ready to help my table.

Day 2 arc — you are on step 4, read logs. profile document submit read logs scale (Part 2) debug 1 2 3 4 5

Everything on this page runs from your clone. Unlike the other pages, this one needs no virtual environment — every command here is sbatch, squeue, sacct, cat or Claude:

cd ~/yens-onboarding-2026

Read your own job’s logs

The job you just submitted wrote log files to logs/ — the .out file has the script’s normal output, the .err file has any errors:

cat logs/extract_*.out
cat logs/extract_*.err

A job that worked leaves an empty .err.

Read a failed job’s logs

Task: Submit a deliberately broken job, read the error log it leaves behind, and fix it with Claude as your reviewer. Reading a failed job’s .err is the first debugging skill you will actually need on the cluster.

Your repo ships several Slurm scripts that are deliberately broken. Fix slurm/fix_me.slurm here; the others are folded away as bonus work at the end of the page. Work with Claude: point Claude Code at the job’s error log and ask it to explain what went wrong and propose a fix. Read its explanation, and if the fix makes sense, approve it and let Claude apply it — you’re the reviewer, so don’t accept a change you don’t understand.

💡 Let it fail before you fix it. A logs/fix_me_*.err file has to exist for you to read, and a bonus exercise later reuses it — so submit it and let it fail rather than reading the script and spotting the bug by eye.

Deactivate your virtual environment before you submit. If your prompt still shows (.venv) from the Profiling page, turn it off:

deactivate

sbatch copies your current environment into the job — --export=ALL is its default — so the job inherits whatever you had active when you submitted. The bug planted in slurm/fix_me.slurm is a missing source .venv/bin/activate. Leave your own venv on and the job inherits it, finds the packages, and succeeds — leaving you an empty .err and nothing to debug.

Submit the first one:

sbatch --reservation=class_cpu slurm/fix_me.slurm

Watch it move through the queue — PD (pending), then R (running), then gone once it finishes:

squeue --me

Once it’s no longer in the queue, check how it ended:

sacct -u SUNetID --format=JobID,JobName,State,Elapsed --starttime=today

When it shows FAILED, read the error log to find out why:

cat logs/fix_me_*.err

Put Claude Code in plan mode first (press Shift+Tab to switch) so it lays out what it would change and why instead of editing right away. Then point it at the error log — a simple prompt is enough:

> Help me troubleshoot logs/fix_me_*.err

Read the plan it comes back with. If the fix makes sense, approve it and let Claude apply it — you’re the reviewer.

You’ll also want a completion email, so ask Claude to add the notification lines to this script:

> Add #SBATCH --mail-type=ALL and #SBATCH --mail-user=SUNetID@stanford.edu to slurm/fix_me.slurm.

Then resubmit — keep debugging and resubmitting until the Slurm email says the job succeeded (exit status 0).

Finish all four pages before you start any bonus. The numbers you write down on one page are the inputs to the next, and Part 2 assumes all four are done.

⭐ Bonus — three more broken jobs

Bonus — Debug fix_me_2.slurm

Same drill, a different script. Submit it, watch it fail, and read its error log:

sbatch --reservation=class_cpu slurm/fix_me_2.slurm
squeue --me
cat logs/fix_me_2_*.err

Troubleshoot with Claude in plan mode (> Help me troubleshoot logs/fix_me_2_*.err), approve the fix if it makes sense, have Claude add the email lines to slurm/fix_me_2.slurm too, and resubmit until the Slurm email says it succeeded.

Bonus — Debug fix_me_3.slurm

One more. Same process:

sbatch --reservation=class_cpu slurm/fix_me_3.slurm
squeue --me
cat logs/fix_me_3_*.err

Troubleshoot with Claude in plan mode, approve the fix, have Claude add the email lines to slurm/fix_me_3.slurm, and resubmit until it completes.

Bonus — Debug extract_form_3_one_file_broken.slurm

The trickiest one: it hides two bugs — one in the Slurm script and one in the Python it runs (scripts/extract_form_3_one_file_broken.py). Submit it, read the error log, and work through both with Claude the same way (plan mode → read the plan → approve → add the email lines → resubmit) until it completes.

⭐ Bonus — let Claude read the log for you

Print mode — claude -p.

Everything above used Claude Code interactively. For a quick, one-off question — or to script it — Claude also runs non-interactively: claude -p "…" (print mode) runs a single prompt, prints the answer, and exits. No session, no back-and-forth.

Point it at a file — one of the other broken scripts, say:

ml claude-code
claude -p "review scripts/extract_form_3_one_file_broken.py and explain what it does" \
  --disallowedTools "Read(./slurm/**)" "Read(./docs/**)"

Why the --disallowedTools flags. Left to itself, Claude reads whatever it thinks is relevant — including the .slurm wrappers holding the other exercises’ planted bugs, and these pages. Denying those two directories puts the answers out of reach, and it tells you when it hits the fence: “slurm/ is in a directory blocked by this session’s permission settings.” Scoping what an agent can see is a habit worth having anyway — the same flag keeps a model away from data it is not allowed to read.

A fence is not a guarantee, though. Those paths are relative to where you run the command, so anything outside this repo is still fair game — and an agent will describe the wrong copy of a file as confidently as the right one, line numbers and all. Check that what it tells you matches the file in front of you.

Or pipe data straight into it. On Linux, every command-line program has two text streams: standard input (stdin, the text coming in) and standard output (stdout, the text it prints out). The pipe symbol | connects them — it takes the stdout of the command on its left and feeds it as the stdin of the command on its right. Because claude -p reads from stdin, you can pipe a file’s contents straight into Claude instead of typing them. Take the fix_me error log you just read and let Claude diagnose it in one line:

cat logs/fix_me_*.err | claude -p "this Slurm job failed — explain the error and suggest a fix"

Because it’s just another command that reads stdin and prints to stdout, you can drop claude -p inside a Slurm job or a shell script and let it work in batch mode — no interactive session at all.

Picture inheriting a whole project you didn’t write — a stack of scripts and Slurm jobs. You can wire claude -p into those jobs so that, as each one runs unattended, Claude documents the run for you: at the end of the script, pipe the results (or the log) to Claude and have it append a plain-English summary of what ran, what the output means, and anything that looks off — straight into the job’s own output. For example, add a few lines to the end of a .slurm script, after the real work:

# ... your extraction / analysis commands above ...

# Let Claude write a human-readable summary of this run into the log
cat results/*.json \
  | claude -p "Summarize what this run produced and flag anything unusual." \
  >> logs/run_summary.txt

Submit a batch of these and you come back to finished jobs that have already documented themselves — what they did, when, and what to look at — without you watching a single one run.


Page last modified: Sep 17, 2026.

Your details

Set these once and the commands on every page fill themselves in. Stored in this browser.

Built with Just the Docs.