Grün, aber leer: Wenn eine Automation ohne Fehler nichts liefert
Auf einen Blick. Ein Statuscode 200 sagt, dass jemand geantwortet hat, und nichts über den Inhalt. Geprüft werden sollte deshalb an jeder Stelle, an der ein Ergebnis weiterverarbeitet wird: Form, Menge und Alter. Sechs Fälle aus unseren Betriebsnotizen von Juli bis September 2026 zeigen, was ohne diese Prüfungen passiert.
Der n8n-Blog beschreibt am Beispiel einer Zahlungs-API, wie ein Lauf grün bleibt und trotzdem falsch rechnet: Der Betrag kommt eines Tages als Text statt als Zahl. Die Anfrage gelingt, der Statuscode stimmt, und erst die Weiterverarbeitung rechnet falsch oder bricht ab. Das Muster kennen wir aus unserem eigenen Betrieb, nur ist es dort meist ein Sprachmodell, ein Suchdienst oder ein Archivierungsjob und keine Zahlungs-API.
Dieser Beitrag ist unabhängig vom Werkzeug gemeint. Wie n8n aufgebaut ist und was es im Eigenbetrieb kostet, steht im Einführungsbeitrag zu n8n. Hier geht es um die Frage danach: Woran merkt man, dass ein grüner Lauf nichts geliefert hat?
Was ein stiller Fehler ist
Ein stiller Fehler ist ein Lauf, der technisch gelingt und fachlich nichts liefert. Der Statuscode ist 200, der Job meldet Erfolg, aber das Feld ist leer, die Liste hat null Einträge oder der Wert hat einen anderen Typ als erwartet. Klassische Überwachung beantwortet, ob etwas läuft, und lässt offen, ob das Ergebnis brauchbar ist.
Eine ähnliche Lücke haben wir schon bei der Überwachung unserer DNS-Resolver beschrieben: Erreichbarkeit ist nicht Gesundheit, nachzulesen im Beitrag Warum ein grüner Uptime-Check nichts beweist. Hier liegt die Lücke eine Ebene höher, im Inhalt der Antwort.
Was der n8n-Blog dazu sagt
Der Beitrag von n8n vom 1. Oktober 2026 nennt drei Änderungen, die gültige HTTP-Antworten liefern und trotzdem die Geschäftslogik brechen: Ein JSON-Objekt wird in ein Array verpackt, ein Aufzählungswert ändert sich und der Ablauf nimmt den falschen Zweig, ein Name wird in zwei Felder geteilt. Sein Rezept: die Antwort direkt hinter dem Abruf gegen ein erwartetes Schema prüfen, Verstöße sofort an Menschen melden und jede Prüfung in der Ausführungshistorie aufbewahren. Dazu gehören laut n8n versionierte Verträge und die Entscheidung, ob jede Anfrage oder nur eine geplante Stichprobe geprüft wird.
Zwei Einordnungen. Der Beitrag stammt vom Hersteller und endet mit der Werbung für das eigene Produkt; die Ideen darin sind aber nicht an n8n gebunden, das schreibt der Beitrag selbst. Und der Begriff stammt aus dem Consumer-Driven Contract Testing: Die Pact-Dokumentation beschreibt, dass dabei nur die Teile einer Schnittstelle geprüft werden, die der Verbraucher tatsächlich nutzt.
Sechs Fälle aus unserem Betrieb
Alle Zeilen stammen aus unseren eigenen Betriebsnotizen. Die Zahlen sind eigene Messungen an unserem LiteLLM-Gateway und den genannten Systemen, die Modelle stehen unter der Tabelle. Diese Aufstellung ist eine Zusammenfassung dieser Notizen und keine neue Messreihe.
| Datum | System | Was grün war | Was gefehlt hat | Messwert |
|---|---|---|---|---|
| 3. Juli 2026 | Bestellimport aus PDF | Modellaufruf lief durch | Wechsel von Instruct- auf Thinking-Modell: Bildzweig lieferte nach 65 s null Felder, Textzweig fehlerhaftes JSON | 65 s, 0 Felder; nach der Korrektur 4,9 s und korrekt |
| 17. August 2026 | Titelvergabe im Chat | Aufruf ohne Fehler | Titel blieb leer, Abbruchgrund length | 256 Token Budget: 5 von 5 leer; 2048: 2 von 5 leer; ohne Denken: 0 von 5 |
| 28. August 2026 | Auswertung von Bewerbungen | HTTP 200 vom Gateway | Inhalt leer, Abbruchgrund length | 400 Token Budget: 12 von 12 leer |
| 28. August 2026 | Prüfung von 36 MCP-Servern | alle 36 antworteten auf initialize und tools/list | Suchdienst lieferte HTTP 200 mit leerer Trefferliste | 36 von 36 grün, erst ein echter Lese-Aufruf fand den Ausfall |
| 30. August 2026 | E-Mail-Archivierung | jede Minute „sync finished successfully“ | ein Postfach archivierte 9,4 Monate lang nichts | Fortschrittszeiger 187 bei 46 vorhandenen Nachrichten |
| 7. September 2026 | Sitzungstitel in unserer Agenten-Oberfläche | Aufruf ohne Fehler | Titel blieb die erste Nachricht, Inhalt null | 64 Token Budget, Abbruchgrund length |
Messträger: Die Titel-Messung vom 17. August lief gegen ein Qwen3.5-122B-A10B-Modell im NVFP4-Format hinter unserem Gateway. Die Messung vom 28. August lief über das Gateway auf der thinking-Spur mit echten Bewerbungstexten statt Fülltext; das Modell nennt die Notiz nicht. Eine Nachmessung vom 29. August mit 8192 Token Budget an sechs echten Lebensläufen reproduzierte den Ausfall nicht (6 von 6 vollständig), einer verbrauchte aber 7755 von 8192 Token. Archiv und MCP-Prüfung sind Zustandsmessungen an laufenden Systemen ohne Modell.
Zwei Zeilen verdienen einen genaueren Blick. Beim Archivierungsjob stand der Fortschrittszeiger über der Wirklichkeit: Das Postfach war irgendwann neu aufgebaut worden, die Nummern der Nachrichten begannen wieder bei eins, und alles Neue lag damit unter dem gespeicherten Zeiger. Der Job war erfolgreich im Sinne seiner Definition, er fand nur nichts. Von rund 500 zugestellten Mails konnten wir 79 zurückholen, der Rest war gelöscht, bevor es jemand merkte. Danach bauten wir eine Prüfung ein, die das Alter der neuesten archivierten Nachricht je Quelle misst, mit 14 Tagen als Schwelle.
Bei den Titeln kam derselbe Fehler zweimal in verschiedenen Anwendungen vor. Ein Reasoning-Modell verbraucht sein Token-Budget für das Nachdenken und liefert keinen Inhalt, ohne dass ein Fehler gemeldet wird. Die Betriebsnotiz vom 28. August hält dazu eine Regel fest: bei fehlender Modellantwort keinen leeren Text zurückgeben, sondern eine eigene Ausnahme werfen, einmal mit doppeltem Budget nachfassen und den Grund protokollieren.
Wo sich Verträge still ändern
In allen Fällen blieb die Schnittstelle gleich, und es änderte sich ein Detail des Inhalts: ein anderes Modell, ein anderes Token-Budget, ein anderer Zustand hinter dem Dienst. Auch Felder können umbenannt werden. Die vLLM-Dokumentation schreibt in ihrer aktuellen Fassung, das Feld reasoning_content heiße jetzt reasoning, und ein Client könne sonst still ein leeres reasoning_content lesen, obwohl reasoning gefüllt ist. Die LiteLLM-Dokumentation vereinheitlicht dagegen auf reasoning_content. Welches Feld bei uns an welcher Stelle ankommt, hängt also davon ab, ob ein Gateway dazwischen sitzt. Wir haben das nicht Version für Version nachgemessen.
Drei Prüfungen, die jeder Pipeline helfen
Form. Direkt hinter dem Abruf prüfen, ob Typ und Pflichtfelder stimmen. Das ist der Teil, den der n8n-Beitrag beschreibt, und er lässt sich in jedem Werkzeug bauen, auch in einem Python-Skript.
Menge. Zählen, wie viel Ergebnis der Lauf erzeugt hat. Eine Liste mit null Einträgen, ein Text mit null Zeichen oder ein Import mit null Datensätzen ist ein Alarm, solange niemand ausdrücklich festgelegt hat, dass null für diesen Job normal ist.
Alter. Messen, wie alt das jüngste Ergebnis ist. Das war die Prüfung, die das Archiv gefunden hätte, und sie braucht keine Kenntnis darüber, warum etwas ausbleibt.
Eine Skizze für die ersten beiden Prüfungen bei einer Chat-Antwort im üblichen Format:
def pruefe(antwort: dict) -> list[str]:
fehler = []
wahl = (antwort.get("choices") or [{}])[0]
text = (wahl.get("message") or {}).get("content")
if not text or not text.strip():
fehler.append("Inhalt leer")
if wahl.get("finish_reason") == "length":
fehler.append("Ausgabe abgeschnitten")
return fehler
Die Skizze ist kein Auszug aus unserem Betrieb. Sie zeigt, wie klein die Prüfung sein kann. Was mit der Fehlerliste passiert, entscheidet der nächste Abschnitt.
Wer den Alarm bekommt
Eine Prüfung, die niemand liest, hilft nicht. Aus unserer Arbeit am Archivierungsjob stammt eine zweite Lehre: Die erste Fassung der neuen Prüfung hing an der Bedingung „bisher wurde nichts gefunden“. Weil ein anderes Postfach seit Wochen dauerhaft auf Fehler stand, wäre die neue Prüfung dauerhaft stumm gewesen. Ein Dauerfehler maskiert dann alle Prüfungen, die nach ihm laufen. Der Trockenlauf hat das gefunden; seitdem hängen beide Bedingungen an einer eigenen Abfrage.
Der Archiv-Check meldet nur bei einem Zustandswechsel, damit nicht alle 15 Minuten dieselbe Mail kommt. Wie wir Dienste mit Uptime Kuma abklopfen und Ausfälle melden lassen, steht im Beitrag zu Uptime Kuma. Wer solche Prüfungen für seine Jobs nicht selbst aufbauen will, findet unser Angebot für den IT-Betrieb. Und wer Sprachmodelle in seine Abläufe einbaut, findet im Überblick KI im Betrieb weitere Fälle, bei denen der Aufbau trägt oder nicht.
Noch zu messen
Offen ist, wie verbreitet die Lücke in unseren eigenen Abläufen heute noch ist. Das haben wir für diesen Beitrag nicht gemessen. Vorgehen: Alle geplanten Jobs je Host auflisten (Cron, Timer, Workflow-Ausführungen), dann je Job prüfen, ob er eine Mengenprüfung hat und ob eine leere Ausgabe einen Alarm auslöst. Ergebnis wäre eine Zahl der Form „n von N Jobs alarmieren bei null Ergebnissen“. Zweite Frage, ebenfalls nur lesend zu beantworten: In den Ausführungshistorien der letzten 30 Tage zählen, wie viele Läufe als erfolgreich markiert sind und null Ausgaben haben.
Was belegt ist und was offen bleibt
Belegt durch die Quellen: die drei Änderungsmuster und das Rezept aus dem n8n-Beitrag, die Beschreibung des Consumer-Driven-Ansatzes bei Pact, die Umbenennung von reasoning_content in reasoning bei vLLM, die Vereinheitlichung bei LiteLLM. Belegt durch unsere Betriebsnotizen: die sechs Fälle in der Tabelle mit den dort genannten Zahlen.
Offen: wie oft das in unseren Abläufen heute vorkommt (siehe oben), ob der Feldname hinter unserem Gateway je nach Version abweicht, und ob die Prüfung des Alters in jedem Job eine sinnvolle Schwelle hat. Quellen zuletzt geprüft: 5. November 2026. Die n8n-Angaben stammen vom Hersteller.
Zehn Minuten am Montag
- Suchen Sie den Job heraus, dessen Ergebnis in eine Mail, eine Buchung oder eine Entscheidung fließt.
- Öffnen Sie seine letzten 30 Läufe und zählen Sie, wie viele Ausgaben jeder Lauf erzeugt hat. Steht dort bei einem als erfolgreich markierten Lauf eine Null, haben Sie den Fehler gefunden.
- Prüfen Sie, ob ein Dauerfehler an anderer Stelle Ihre Fehlermeldung stummschaltet.
- Legen Sie eine Regel fest: null Ausgaben sind ein Alarm, und er geht an eine Person, die ihn auch liest.
Weiterführende Quellen
Was ist ein stiller Fehler in einer Automation?+
Ein Lauf, der technisch gelingt und fachlich nichts liefert. Der Statuscode ist 200, der Job meldet Erfolg, aber das Feld ist leer, die Liste hat null Einträge oder ein Wert hat einen anderen Typ als erwartet. Fehlerbehandlung greift hier nicht, weil formal nichts schiefgegangen ist.
Reicht ein Schema-Check, um solche Fehler zu finden?+
Er findet geänderte Felder und Typen, etwa eine Zahl, die plötzlich als Text ankommt. Eine leere, aber formal gültige Antwort findet er nur, wenn das Schema Mindestlängen oder Mindestanzahlen vorschreibt. Deshalb gehört eine zweite Prüfung dazu, die zählt, wie viel Ergebnis ein Lauf tatsächlich erzeugt hat.
Warum liefert ein Reasoning-Modell manchmal eine leere Antwort?+
Weil Nachdenken und Antwort sich ein Token-Budget teilen können. Ist es aufgebraucht, bevor das erste Zeichen der Antwort kommt, gibt die Schnittstelle einen leeren Inhalt mit dem Abbruchgrund length zurück. Bei uns war das in den Messungen vom 17. und 28. August 2026 der Fall, ohne Fehlermeldung.
senn-tech