Was schiefgeht, wenn Claude Code unbeaufsichtigt über Nacht läuft
Coding-Agents lassen sich per launchd, cron oder geplanter Aufgabe leicht für Nachtläufe einrichten. Doch aus den nächtlichen Ergebnissen am Morgen etwas Nützliches zu machen, erweist sich in der Praxis als deutlich schwieriger, wie Berichte von Entwicklern zeigen.

Einen Coding-Agent zu planen dauert nur wenige Minuten. Eine launchd-Plist, eine Cron-Zeile oder eine geplante Desktop-Aufgabe startet Claude Code oder Codex um 2 Uhr nachts. Bis 8 Uhr morgens etwas Nützliches daraus zu bekommen, ist dagegen schwieriger.
Ich habe in letzter Zeit gelesen, was Menschen veröffentlichen, die Agenten per Timer laufen lassen: einen dev.to-Bericht über eine Woche als geplanter Agent, den HN-Thread zu tmux und Claude Code, einen r/LLMDevs-Thread, in dem gefragt wird, was man eigentlich aufzeichnen sollte, wenn ein Agent unbeaufsichtigt läuft, sowie eine Handvoll neuerer Beiträge. Immer wieder tauchen dieselben Fehler auf, und nur sehr wenige davon bestehen darin, dass das Modell schlechten Code schreibt. Die meisten sind Handwerkskunst-Probleme. Hier sind sie, gruppiert danach, was man am Morgen vorfindet.
Das Ding, das den Lauf starten sollte, lief nicht.
Was hilft: Läufe über launchd starten (auf Linux systemd), nicht über ein Anwendungsfenster. launchd hat auf einem Laptop zudem einen Vorteil gegenüber cron. Wenn die Maschine zum geplanten Zeitpunkt schläft, überspringt cron den Job, während launchd ihn ausführt, sobald die Maschine aufwacht. Halte den Mac für das benötigte Zeitfenster wach (caffeinate -i deckt Ruhezustand bei Untätigkeit ab, nicht aber einen zugeklappten Deckel im Batteriebetrieb), und führe die Session an einem Ort aus, zu dem du dich erneut verbinden kannst.
Aus Sicht des Schedulers sieht dieser hier völlig in Ordnung aus.
Ein Beitrag aus dieser Woche liefert ein anschauliches Beispiel. Ein launchd-Job feuerte an zwei aufeinanderfolgenden Nächten um 21:00 Uhr und beendete sich eine Sekunde später wieder. Das Runbook wurde dem Agent-CLI als Argument übergeben, begann mit YAML-Frontmatter, und das CLI interpretierte --- als unbekannte Option und brach mit Exit-Code 1 ab. Die Lösung bestand darin, -- vor den Prompt zu setzen, damit alles danach als Text gelesen wird. Der Exit-Status lag seit der ersten Nacht in launchctl list, und niemand hatte ihn geprüft.
Was hilft: Prüfe die Ausgabe selbst. Existiert die Datei, stammt sie aus der heutigen Nacht, enthält sie überhaupt etwas? Der Exit-Code und die letzte Nachricht des Agenten können beide unauffällig aussehen, obwohl dem nicht so ist.
Ein Berechtigungsdialog um 2 Uhr nachts bedeutet, dass der Lauf nichts tut, bis man aufwacht. Genauso verhält es sich mit jedem Schritt, der ein menschliches Ja erfordert, etwa der Veröffentlichung von etwas Öffentlichem. Der Beitrag zum geplanten Agenten ergänzt Browser-Anmeldungen: Eine hielt etwa einen Tag lang, der nächste Lauf landete auf einer Login-Seite, und ein Agent sollte keine Passwörter eintippen.
Dieser Beitrag lohnt sich vor dem ersten Overnight-Lauf. Der Autor hatte Claude Code über Nacht im Auto-Modus an einer iOS-App arbeiten lassen, wobei ein Klassifikator die Berechtigungsanfragen beantwortet. Ein Subagent sollte einem Skript, das rm -rf ausführt, einen Home-Verzeichnis-Schutz hinzufügen und führte den Test aus, bevor er den Schutz schrieb.
Dem Test wurde das echte Home-Verzeichnis übergeben, und etwa 9 Tage unpushter Commits verschwanden mit dem lokalen.git. Seine Erklärung: Die Berechtigungsprüfungen und seine eigenen Hooks betrachten nur die eine Befehlszeile, die Claude eintippt, und können keinen Pfad sehen, der innerhalb eines Skripts an rm -rf übergeben wird, das dieser Befehl ausführt. Seine wichtigsten Verteidigungen sind inzwischen die Sandbox (sandbox.enabled: true und allowUnsandboxedCommands: false in den Einstellungen), ein Backup außerhalb des Mac und das sofortige Pushen von Commits nach deren Freigabe.
Auch kleinere Kollisionen zeigen sich. In der Issue-Schleife kollidierte eine Reihe von Refactor-PRs an CLAUDE.md und README.md, daher bekommt jedes Issue inzwischen ein eigenes git worktree und kann über eine Zeile wie After #N hinter einem anderen zurückgehalten werden. Und ein Ask HN aus dieser Woche macht deutlich, dass das Risiko wächst, wenn ein geplanter Agent MCP-Server und Zugangsdaten auf der Maschine hat.
Bei einem Abo kostet eine schlechte Nacht den nächsten Tag. Im agent-usage-guard Show HN schrieb ein Kommentator, der mehr als einmal ein ganzes Nutzungsfenster innerhalb weniger Minuten verbraucht hatte, einen Hook, der Subagents daran hindert, über 80% des Fensters hinaus gestartet zu werden. Er berichtet, sein größter Ausbruch sei von 365 gestarteten Agenten auf 27 gesunken.
Die Issue-Schleife liest dieselben Zahlen, die /usage vor jedem Issue anzeigt, und beendet die Nacht, wenn der heutige Tag 10 Punkte der Woche verbraucht hat, die Woche über 70% liegt oder das 5-Stunden-Fenster über 80% ist. Wenn sie die Zahlen nicht lesen kann, nimmt sie 100% an und stoppt. An dem einen Wochenende, an dem der Autor die Nachtschwelle auf 60 Punkte anhob, stieg die Woche von 20% auf 48%.
Ein Lauf, der problemlos verlief, aber nichts Lesbares hinterließ, kostet trotzdem einen Morgen, weil man am Ende jede Session öffnet, um herauszufinden, was passiert ist. Im tmux-Thread nannte ein Kommentator die Sessions ein Implementierungsdetail, in das er nur springen wolle, wenn etwas schiefgelaufen ist. Ein anderer baute sein eigenes Setup hauptsächlich, um zu sehen, welche Sessions noch laufen, welche Hilfe brauchen und welche fertig sind.
Die billigste Lösung sind ein paar Zeilen am Ende jedes Briefings:
Wenn du fertig bist, schreibe einen kurzen Bericht nach reports/<date>.md: was du geändert hast, welche Dateien, welche Annahmen du getroffen hast und was du von mir brauchst. Morgens liest man die Berichte und öffnet nur dann ein Transkript, wenn ein Bericht meldet, dass etwas schiefgegangen ist. Der Beitrag zum geplanten Agenten beschreibt außerdem eine Schleife, auf die man achten sollte: Wenn sich nichts außerhalb ändert, liest jede neue Session den Plan, findet nichts Neues und schreibt denselben Plan für morgen. Ein in den Plan geschriebenes Entscheidungsdatum (wenn X bis Tag 7 immer noch nicht live ist, tue Y) beendet das.
Ich wollte Agenten außerhalb meiner Arbeitszeiten lokal auf dem Claude-Abo laufen lassen, das ich ohnehin bezahle, und habe dafür eine Mac-App gebaut: Overboard. Jedes geplante Briefing (jeder Prompt oder Plugin-Slash-Command: eine Security-Review, ein Blogbeitrag, Social Discovery) läuft als echte Claude-Code-Session in seinem Projektordner, die man beobachten oder übernehmen kann. Es gibt ein Keep-Awake-Menü, damit der Mac nicht einschläft, während Agenten ihn brauchen, und jede Abteilung hat einen Captain, der die letzten Läufe prüft und mich nur fragt, wenn er feststeckt. Sessions laufen im Auto-Modus, sodass Abschnitt 4 hier genauso gilt wie überall sonst: Sandbox, Deny-Liste und Backup muss man weiterhin selbst einrichten. Der Mac muss wach und eingeloggt sein.
Automatisch übersetzt. Das Original auf Englisch ist unten aufklappbar.
Original (Englisch) anzeigen
Scheduling a coding agent takes a few minutes. A launchd plist, a cron line or a desktop scheduled task will start Claude Code or Codex at 2am. Getting something useful out of it by 8am is harder.
I've been reading what people who run agents on a timer have posted lately: a dev.to write-up of a week running as a scheduled agent, the HN thread on tmux and Claude Code, an r/LLMDevs thread asking what you actually record when an agent runs unattended, and a handful of newer posts. The same failures come up again and again, and very few of them are the model writing bad code. Most are plumbing. Here they are, grouped by what you find in the morning.
The thing that was supposed to start the run wasn't running.
What helps: start runs from launchd (systemd on Linux), not from an app window. launchd has one more advantage over cron on a laptop. If the machine is asleep at the scheduled time, cron skips the job, while launchd runs it when the machine wakes. Keep the Mac awake for the window you need ( caffeinate -i covers idle sleep, not a closed lid on battery), and run the session somewhere you can reattach to.
From the scheduler's side this one looks fine.
A post from this week has a clean example. A launchd job fired at 21:00 two nights in a row and exited one second later. The runbook was handed to the agent CLI as an argument, it started with YAML frontmatter, and the CLI parsed --- as an unknown option and quit with exit code 1. The fix was putting -- before the prompt so everything after it is read as text. The exit status had been sitting in launchctl list since the first night, and nobody checked it.
What helps: check the output itself. Does the file exist, is it from tonight, does it have anything in it. The exit code and the agent's last message can both look fine when it doesn't.
A permission prompt at 2am means the run does nothing until you wake up. Same for any step that needs a human yes, like publishing something public. The scheduled-agent post adds browser sign-ins: one lasted about a day, the next run hit a login page, and an agent shouldn't be typing passwords.
This post is worth reading before your first overnight run. The author had Claude Code working on an iOS app overnight in auto mode, where a classifier answers the permission prompts. A subagent asked to add a home-directory guard to a script that runs rm -rf ran the test before writing the guard, the test was given the real home directory, and about 9 days of unpushed commits went with the local.git. Their explanation: the permission checks and their own hooks look at the one command line Claude types, and they can't see a path passed to rm -rf inside a script that command runs. Their main defenses now are the sandbox ( sandbox.enabled: true and allowUnsandboxedCommands: false in settings), a backup off the Mac, and pushing commits soon after approving them.
Smaller collisions show up too. In the issue loop, a batch of refactor PRs collided on CLAUDE.md and README.md, so each issue now gets its own git worktree and can be held behind another one with an After #N line. And an Ask HN from this week makes the point that the risk grows when a scheduled agent has MCP servers and credentials on the machine.
On a subscription, a bad night costs you the next day. In the agent-usage-guard Show HN, a commenter who had burned a whole usage window in minutes more than once wrote a hook that stops subagents from spawning past 80% of the window. They report their biggest burst went from 365 spawned agents to 27.
The issue loop reads the same numbers /usage shows before every issue and ends the night when tonight has used 10 points of the week, the week is past 70%, or the 5-hour window is past 80%. If it can't read the numbers it assumes 100% and stops. The one weekend its author raised the night allowance to 60 points, the week went from 20% to 48%.
A run that went fine but left nothing to read still costs you a morning, because you end up opening every session to find out what happened. In the tmux thread one commenter called the sessions "an implementation detail" they only want to jump into "when something is wrong". Another built their own setup mainly to see which sessions are still running, which need help and which are done.
The cheapest fix is a few lines at the end of every brief:
When you finish, write a short report to reports/<date>.md: what you changed, which files, anything you assumed, and what you need from me. Enter fullscreen mode Exit fullscreen mode In the morning you read the reports and only open a transcript when a report says something went wrong. The scheduled-agent post also describes a loop to watch for: when nothing outside changes, each fresh session reads the plan, finds nothing new and writes the same plan for tomorrow. A decision date written into the plan ("if X still isn't live by day 7, do Y") ends it.
I wanted to run agents locally off-hours on the Claude subscription I already pay for, so I built a Mac app for it, Overboard. Each scheduled brief (any prompt or plugin slash command: a security review, a blog post, social discovery) runs as a real Claude Code session in its project folder that you can watch or take over. There's a keep-awake menu so the Mac doesn't sleep while agents need it, and each department has a captain that reviews the last runs and only asks me when it's stuck. Sessions run in auto mode, so section 4 applies to it as much as anything else: the sandbox, the deny list and the backup are still yours to set up. The Mac has to be awake and logged in.