Betriebsteams kennen OpenClaw-Gateways vor allem anhand erfreulicher Logs—Produktion lehrt jedoch das Vokabular der Exit-Codes. Im Jahr 2026 kapselt macOS-launchd Node-Laufzeiten gleichermaßen auf einem Studio-Mac-mini wie auf einer gemieteten Cloud-Instanz: 137 flüstert meist nach Speicherdruck, 143 steht häufig für ein höfliches SIGTERM beim Neuladen, und rasende Neustarts deuten eher auf plist-Fehler als auf Modellqualität. Dieses Playbook ordnet Codes Signale zu, zeigt filterbare unified Logs ohne Informationsflut, verknüpft Symptome mit Gateway-doctor-Diagnosen und erklärt, wann ein Activity-Monitor-Sample nötig ist, bevor Sie die Parallelität wieder anheben.
Ergänzend helfen LaunchAgent-Neustart- und Recovery-Muster für saubere Zyklen sowie Speicher- und Kontext-Pruning, sobald Gespräche und Tool-Transkripte ohne Obergrenze wachsen.
Exit-Code-Spickzettel
| Code | Typische Bedeutung | Erste Checks |
|---|---|---|
| 0 | Sauberes Herunterfahren | Absichtlicher Stopp gegen Watchdog abgrenzen |
| 1 | Generischer Node-Fehler | Stderr-Pfad lesen; im Vordergrund wiederholen |
| 137 | OOM / SIGKILL | Speicherdruck, Tool-Ausgabegröße, Modellkontext |
| 143 | SIGTERM | launchd-Reload, manuelles kill, Deploy-Skript |
macOS zeigt für GUI-Apps Jetsam-Ereignisse; Daemons hinterlassen Brotkrumen im unified logging mit Grundstrings—lernen Sie die exakte Schreibweise Ihrer Bundle-IDs, damit Prädikate schmal bleiben und Audits SSH-freundlich bleiben.
Halten Sie eine interne Legende bereit, welche Dienste noch alte Wrapper-Skripte nutzen, die Exit-Codes maskieren. Ohne Legende interpretieren On-Call-Ingenieurinnen 137 fälschlich als „Modell zu groß“, obwohl nur ein Logrotate fehlte.
launchd, ThrottleInterval und Crash-Schleifen
Beendet ein Job mit Nicht-Null, wendet launchd Backoff an. Kombiniert die plist aggressives KeepAlive mit einem Prozess, der in unter einer Sekunde stirbt, entsteht eine Wand identischer Zeitstempel, die die erste echte Fehlerzeile verdeckt. Heben Sie ThrottleInterval vorübergehend auf etwa 10 Sekunden an, beheben Sie die Ursache, und stellen Sie danach einen strafferen Wert für Produktionsreaktivität wieder her.
Dokumentieren Sie, ob RunAtLoad aktiv ist: Falsche Positive entstehen, wenn Teams Agenten manuell entladen, Automatisierung sie Minuten später neu lädt und der wahre Auslöser im Rauschen untergeht.
Archivieren Sie plist-Versionen neben dem Gateway-Binary-Hash—sonst vergleichen Postmortems Äpfel mit Birnen, sobald jemand „nur“ einen Kommentar formatiert hat.
log show: lesbare Prädikate
log show --last 30m --predicate \
'subsystem == "com.apple.xpc.launchd" AND eventMessage CONTAINS[c] "openclaw"'
Verengen Sie weiter mit process == "launchd" plus Ihrem Label-String. Exportieren Sie JSON für Postmortems, damit Prüfer grep nutzen können, ohne interaktive Shells zu brauchen.
Wenn Logs riesig werden, splitten Sie nach Zeitfenstern und annotieren Sie jede Datei mit Ticket-ID—sonst verlieren sich Korrelationen zwischen Gateway und Reverse-Proxy.
Console.app-Workflows
- Favorit „Gateway-Exits“ anlegen, der Subsystem- und Textfilter kombiniert.
- Stream starten, bevor Sie reproduzieren; direkt nach dem Crash pausieren, damit Puffer nicht verloren gehen.
- sysdiagnose nur anhängen, wenn Dateisystem oder Kext im Verdacht steht—sonst bleiben Beweise schlank.
Teilen Sie Screenshots der Filter mit Support, damit Remote-Teams dieselbe Sicht bekommen wie vor Ort.
Speicherdruck und Tool-Fächer
Exit 137 korreliert oft mit parallelen Tool-Aufrufen, die jeweils mehrere Megabyte stdout puffern. Deckeln Sie gleichzeitige Tools auf drei, wenn der Host nur 8 GB vereinheitlichten Speicher hat, oder senken Sie Modellkontext-Fenster unter den Spike, den Sie im Speicher-Tab des Aktivitätsmonitors sahen. Wenn der Kompressor aktiv wird, steigt die Latenz bevor der Killer zuschlägt—das ist ein Frühindikator.
Richten Sie Pruning-Richtlinien am Speicher-Artikel aus: Transkripte rotieren, JSON-Tiefe begrenzen und übergroße Anhänge am Gateway ablehnen, statt sie in Node parsen zu lassen.
Überwachen Sie RSS-Hochwasser pro Release; plötzliche Treppenstufen nach einem Provider-Upgrade sind ein klassisches Signal für größere Standardantworten.
Wann den Node-Prozess samplen
Wenn die CPU länger als zwei Minuten bei 100 % klebt, ohne Fortschrittslogs, erfassen Sie ein Sample aus dem Aktivitätsmonitor und archivieren Sie es neben der plist-Version. Samples zeigen enge Schleifen in Middleware, die im Stderr nie als klassischer Stack auftauchen.
Klären Sie vorab mit Datenschutz, ob Samples personenbezogene Strings enthalten—dann redigieren Sie vor dem Teilen.
Plist-Hygiene: KeepAlive, RunAtLoad
Unter KeepAlive sollte SuccessfulExit nur dann greifen, wenn Exit 0 wirklich „ungesund“ bedeutet. Falsch gesetzte Booleans lassen launchd gesunde Shutdowns neu starten und verbrennen CPU-Guthaben auf Cloud-Mac-Hosts. Validieren Sie mit launchctl print gui/$UID/ihr.label und screenshotten Sie die Ausgabe fürs Change-Management.
Prüfen Sie, ob mehrere plist-Varianten im Umlauf sind—Homebrew-Pfade, manuelle Kopien und CI-Artefakte liefern sonst widersprüchliche Labels.
Warum Linux-CI nicht reproduziert
CI-Container teilen weder denselben Speicher-Kompressor, noch dieselbe launchd-Lebenszyklussemantik oder Keychain-Dialoge. Behandeln Sie Linux-Tests als Linting: Vor dem Promoten eines Gateway-Builds gehört ein Rauchtest auf macOS. Ein gemieteter Mac-mini schließt die Lücke für etwa 16,9 USD pro Tag, statt Laptops zu verschicken.
Dokumentieren Sie, welche CI-Stufen bewusst auf Linux bleiben und welche macOS-only sind—sonst glauben PMs fälschlich an vollständige Abdeckung.
Postmortem-Vorlage
- Zeitleiste von der letzten gesunden Request-ID bis zur ersten Crash-Zeile.
- Exit-Code, Signal und launchd-Grundstring.
- Speicher-Hochwasser und parallele Tool-Anzahl.
- Doctor-Ausgabe-Hash und Konfigurations-Diff seit letztem Deploy.
- Follow-up: Codeänderung, plist-Änderung oder Kapazitätsänderung.
Einheitliche Vorlagen verkürzen Review-Zyklen mit Compliance, weil jede Ausgabe dieselben Felder füllt.
Stderr-Rotation und volle Platten
Einige Gateways beenden mit Code 1, wenn StandardErrorPath nicht anhängen kann, weil das Volume voll ist. Unified Logging rotiert zwar, einzelne Dateien nicht. Überwachen Sie freien Speicher auf /private/var und Ihrem Log-Verzeichnis; halten Sie mindestens 5 GB frei auf geteilten Mac-mini-Hosts, auf denen mehrere Agenten ausführliche Tool-Dumps schreiben.
Dokumentieren Sie newsyslog- oder logrotate-ähnliche Hüllen im Runbook statt unkontrolliert wachsender Einzeldateien—das Parsen einer 12 GB großen Stderr-Datei unter Stress erzeugt sekundäre Ausfälle.
Signal-Hygiene in Deploy-Skripten
Blue-Green-Skripte senden oft SIGTERM, warten 15 s und eskalieren dann zu SIGKILL. Wenn Node SIGTERM abfängt, um HTTP-Verbindungen auszulaufen, Tool-Aufrufe aber das Grace-Fenster sprengen, protokolliert launchd 137, obwohl Betrieb „sauberes Herunterfahren“ annahm. Verlängern Sie die Grace-Phase oder senken Sie laufende Tool-Fächer, bevor Binaries getauscht werden.
Ein /readyz-Endpunkt, der vor SIGTERM auf falsch springt, stoppt Load-Balancer schneller als allein Node-Flags zu tweaken.
Minimaler Flight-Recorder
Exportieren Sie process_start_timestamp_seconds, process_exit_code und rss_bytes_max selbst in kleinen Installationen nach Prometheus. Wenn Exit-Codes springen, erzählen diese drei Serien ohne Laptop, ob Speicher, Deploy-Churn oder Konfiguration das Problem ist.
Halten Sie Dashboards bewusst dünn—zu viele Metriken verwässern Alarme.
TCC, Keychain und scheinbare 143er
Manchmal beendet launchd einen Job mit SIGTERM, weil ein Pflege-Skript parallel läuft oder ein Benutzer manuell entlädt. In anderen Fällen blockiert TCC den Zugriff auf Dateien, Middleware fängt den Fehler ab und beendet kontrolliert—dennoch sieht das Monitoring einen 143er. Korrelieren Sie mit Console-Meldungen zu Privacy und mit doctor, bevor Sie Speicher aufstocken.
Keychain-Prompts auf headless Servern enden oft in Timeouts; dokumentieren Sie nicht-interaktive Pfade und Testnutzerprofile.
FAQ
Bedeutet 137 immer OOM?
In der Regel ja bei Gateways; dennoch mit Speicherdiagrammen bestätigen.
Warum 143 nach Deploy?
launchd beendete den alten Prozess beim Reload.
Wo liegt stderr?
In StandardErrorPath der LaunchAgent-plist oder über log stream.
Wann Mac mini mieten?
Wenn treues launchd- und Speicherverhalten ohne Hardwarekauf nötig ist.
Exit-Code-Archäologie ist mühsam, aber günstiger als Ausfallminuten. Physischer Mac mini mit Apple Silicon reproduziert launchd-Backoff, Speicher-Kompression und Dateideskriptor-Defaults anders als Linux-Staging. MacHTML vermietet Maschinen mit SSH und VNC, damit Sie während eines Release-Wochenendes einen Diagnose-Host online lassen, Console-Streams sichern und montags wieder abschalten können—elastische Kapazität ohne weiteren CapEx-Antrag.
Leise Hardware hilft zudem, wenn Sie in einer Videokonferenz Logs vorlesen, ohne dass Lüfter die Verständlichkeit fressen. Für kurze Hochlastphasen reicht oft ein Cloud-Mac-mini zu etwa 16,9 USD pro Tag, um dasselbe Verhalten wie beim Kunden zu sehen, ohne neue Büromöbel zu bestellen.
OpenClaw-Exits auf echtem macOS-launchd nachstellen
Mieten Sie einen Cloud-Mac-mini, um Exit-Codes, plist-Reload-Verhalten und Console.app-Beweise zu validieren, bevor Gateway-Änderungen ausgerollt werden.