Code-Knoten frieren ein

Code-Knoten eingefroren

Problem/Fehler/Frage beschreiben

Mein Workflow funktioniert perfekt, aber wenn ich dem LLM (OpenAI) einen Speicher hinzufüge, der sich fast in der Mitte des Workflows befindet, frieren viele Code-Knoten ein, die sich vor dem HTTP-Knoten befinden (zum Senden der Payload an das Dashboard)

Ich stoße auf ein schwerwiegendes Leistungsproblem, bei dem meine Code-Knoten eingefroren sind und schließlich ein Timeout erhalten, aber nur wenn LLM-Speicher im Workflow vorhanden ist.

Mein Workflow verarbeitet eingehende JSON-Daten mit Hilfe von mehreren Standard-Code-Knoten (Datenbereingung und Validierung). Weiter unten im Workflow habe ich einen LLM-Knoten (OpenAI) mit einer angehängten Speicherkomponente.

Wenn ich den Workflow ohne den LLM-Speicher ausführe, wird alles perfekt und sofort ausgeführt. Jedoch, sobald ich dem LLM einen Speicher hinzufüge, bleiben mehrere Code-Knoten, die vor einer HTTP-Anforderung ausgeführt werden, in einer unendlichen Blockierung stecken.

Welche Fehlermeldung erhalten Sie (falls vorhanden)?

Etwa so: Es gibt keine Fehlermeldung mehr, nur endlose Ausführung. Fehler:
Task execution timed out after 300 seconds
Der Task Runner hat zu lange bei dieser Aufgabe gezögert, weshalb vermutet wurde, dass er nicht antwortet, und wurde neu gestartet. Die Aufgabe wurde abgebrochen. Sie können Folgendes versuchen: 1. Optimieren Sie Ihr Skript, um lange laufende Aufgaben zu vermeiden, z. B. durch Verarbeitung von Daten in kleineren Chargen. 2. Stellen Sie sicher, dass alle Pfade in Ihrem Skript beendet werden können, d. h. keine Endlosschleifen. 3. Wenn Ihre Aufgabe vernünftigerweise mehr als 300 Sekunden dauern kann, erhöhen Sie das Timeout mithilfe der Umgebungsvariablen N8N_RUNNERS_TASK_TIMEOUT.

Informationen zu Ihrem n8n-Setup

  • n8n-Version: 2.11.3
  • Datenbank (Standard: SQLite): Standard
  • n8n EXECUTIONS_PROCESS-Einstellung (Standard: own, main): Standard
  • n8n wird ausgeführt über (Docker, npm, n8n cloud, Desktop-App): Docker
  • Betriebssystem: Windows

Hey @sherazbintahir, während du auf eine Antwort wartest, könnten diese Ressourcen hilfreich sein:

[details=“Empfohlene Ressourcen”]

Automatisch zu deiner Frage zugeordnet.

Docs:

Forum:

ist eine spezifische n8n-Sicherheitsmaßnahme. Das bedeutet, dass der JavaScript-Code in deinen Code-Knoten länger als 300 Sekunden läuft, was dazu führt, dass der n8n Task Runner annimmt, dass er in einer Endlosschleife steckt oder eine unmöglich große Aufgabe verarbeitet, weshalb er ihn gewaltsam beendet.

Da dies nur passiert, wenn du Memory an das LLM anhängst, ändert die Memory-Komponente grundlegend die Datenstruktur, Größe oder das Verhalten der Daten, die in deine nachgelagerten Code-Knoten fließen.

Wenn Memory angehängt ist, kann der LLM-Knoten (oder die Chain/Agent, zu der er gehört) den gesamten Gesprächsverlauf oder ein großes Memory-State-Objekt in den Hauptdatenstrom übergeben, anstatt nur die endgültige KI-Antwort.

  • Das Problem: Wenn deine Code-Knoten versuchen, eine Eingabe zu verarbeiten, bereinigen oder JSON.stringify() durchzuführen, die jetzt hunderte oder tausende historischer Nachrichten enthält, wird das Problem leicht das 300-Sekunden-CPU-Timeout überschreiten.
  • Die Lösung: Du musst die Daten unmittelbar nach dem LLM-Knoten auf nur das reduzieren, was das Dashboard sofort benötigt.
    • Füge einen temporären Code-Knoten direkt nach dem LLM-Knoten mit diesem Code hinzu, um zu sehen, was tatsächlich übergeben wird:
// Überprüfe, wie viele Elemente und die Größe der Daten
const items = $input.all();
console.log("Gesamtelemente:", items.length);
console.log("Erste Element-Schlüssel:", Object.keys(items[0].json));
return items;
  • Wenn du ein massives messages-Array oder Memory-Objekt siehst, aktualisiere deine nachgelagerten Code-Knoten so, dass sie nur das spezifische Feld extrahieren, das du benötigst (z. B. item.json.message.content oder item.json.text) und den Rest vor der Verarbeitung verwerfen.

Memory-Objekte in n8n (besonders bei LangChain-Integrationen) können manchmal zirkuläre Referenzen enthalten (wo ein Objekt auf sich selbst verweist).

  • Das Problem: Wenn deine Code-Knoten JSON.stringify($input.all()) verwenden oder das gesamte Eingabeobjekt in eine benutzerdefinierte Parse-Funktion übergeben, kann eine zirkuläre Referenz dazu führen, dass die JavaScript-Engine in eine Endlosschleife eintritt und versucht, das Objekt zu serialisieren, was zum 300-Sekunden-Timeout führt.
  • Die Lösung: Stringifiziere nie das gesamte $input oder $input.all(), wenn es LLM/Memory-Ausgaben enthält. Extrahiere immer zuerst die primitiven Zeichenfolgenwerte:
  // FALSCH: Kann hängen bleiben, wenn zirkuläre Referenzen existieren
  // const payload = JSON.stringify($input.all()); 

  // RICHTIG: Extrahiere nur die primitiven Daten, die du brauchst
  const cleanData = $input.all().map(item => ({
    response: item.json.message?.content || item.json.text,
    // füge hier weitere spezifische Felder hinzu
  }));
  const payload = JSON.stringify(cleanData);

Wenn deine Code-Knoten while-Schleifen, rekursive Funktionen oder .reduce()-Methoden verwenden, die von der Struktur des eingehenden JSON abhängen, könnte die Memory-Komponente diese Struktur verändert haben.

  • Das Problem: Zum Beispiel, wenn dein Code eine while-Schleife hat, die ein Array verarbeitet, bis es leer ist, aber die Memory-Komponente versehentlich ein verschachteltes Array eingibt, das sich ständig regeneriert oder nicht die Beendigungsbedingung erfüllt, wird die Schleife endlos laufen.
  • Die Lösung: Überprüfe alle while-Schleifen in deinen Code-Knoten. Füge einen „Sicherheitszähler

Wie ich sagte, ist der Speicher, der mit dem LLM verbunden ist, in der Mitte des Workflows.

Und sobald ich den Speicher hinzugefügt habe, bin ich auf Probleme mit mehreren Code-Knoten gestoßen, und einige Code-Knoten befinden sich am Anfang des Workflows (bevor der LLM-Speicher-Knoten überhaupt ausgeführt wird).

Ohne Speicher wird der Workflow ohne Probleme ausgeführt, aber mit Speicher treten im selben Workflow Probleme am Code-Knoten auf.

Da du das nicht klar angegeben hast, nehme ich an, es ist nach dem AI Agent passiert

Das ist klarer. Das klingt für mich wie ein Speicher-Regressionsproblem

Hilft ein Update auf die neueste stabile Version von n8n?

Hallo @sherazbintahir
Code-Knoten, die rein durch das Vorhandensein eines Sub-Knotens hängen, einschließlich solcher, die davor ausgeführt werden, bedeutet, dass der Task Runner den Typ dieses Sub-Knotens nicht auflösen kann. Alles, was einen Code-Knoten veranlasst, den Hauptprozess um zusätzlichen Kontext zu fragen – eine $('Node Name')- oder $node["Node Name"]-Referenz oder ein require() eines externen Moduls – sendet den Runner zurück, um den Workflow neu zu erstellen, und ein Sub-Knoten-Typ, den er nicht auflösen kann, lässt diese Anfrage unanswortbar, bis nach 300 Sekunden der Timeout eintritt. Deine

Danke, das wird mir sehr helfen. Aber ich bin hier verwirrt, weil mein kompletter Workflow (120+ Knoten) perfekt ohne Fehler funktioniert, aber wenn ich den Speicher mit dem LLM verbinde (KI-Agent-Knoten mit OpenAI + Speicher), tritt dieses Problem auf.
Für weitere Informationen: Im Workflow ohne Speicher verwende ich den OpenAI-Knoten direkt. Und ich habe dieses Problem nicht bei allen Code-Knoten, sondern nur bei einigen.

Gelbe Box: Wo ich Speicher mit dem LLM verbinde.
Rote Punkte: Wo ich Code-Knoten-Probleme habe. Die meisten Knoten sind diejenigen, in denen ich die Nutzlast vorbereite/aufbaue, um sie zum Dashboard zu senden.

Hallo @sherazbintahir

Hast du schon versucht, zu PostgreSQL zu wechseln, um SQLite Database Locking auszuschließen?

services:
  postgres:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=n8n_user
      - POSTGRES_PASSWORD=n8n_password
      - POSTGRES_DB=n8n_db
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n_user -d n8n_db"]
      interval: 5s
      timeout: 5s
      retries: 5

  n8n:
    image: n8nio/n8n:2.11.3
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n_db
      - DB_POSTGRESDB_USER=n8n_user
      - DB_POSTGRESDB_PASSWORD=n8n_password
      - EXECUTIONS_PROCESS=own
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  postgres_data:

Hi @sherazbintahir Das ist keine Langsamkeit, deine Code-Knoten sind deadlocked, nicht ausgelastet.

Seit v2.0 laufen alle Code-Knoten in einem separaten Task-Runner-Prozess. Wenn ein Skript nur input/input / input/json verwendet, erhält es eine schlanke Payload und läuft sofort. Aber wenn es ('NodeName') oder ('Node Name') oder node['Node Name'] verwendet, muss der Runner den gesamten serialisierten Workflow von n8n anfordern und ihn neu aufbauen – und das erfordert das Auflösen aller Knotentypen auf der Leinwand, einschließlich Unterknoten. Wenn du den Memory-Unterknoten anhängst und der Runner trifft auf einen Typ, den er nicht auflösen kann, wird die Anfrage nie zurückgegeben, und dein Code-Knoten wartet endlos, bis der 300-Sekunden-Watchdog ihn beendet. Genauso wie #20752.

Das erklärt auch, warum nur einige deiner Code-Knoten fehlschlagen – die funktionierenden sind diejenigen, die nie außerhalb ihrer eigenen Eingabe gehen.

Kannst du zwei Dinge überprüfen?

  1. Führe es mit Memory aus und grep deine Logs:
   docker logs -f <n8n-container> | grep -i "unrecognized node type"
  1. Öffne einen der eingefrorenen Code-Knoten – enthält er $('...') oder $node[...] irgendwo?

Wenn ja zu beiden, die Lösung ist schnell: Füge einen Set-Knoten davor ein und übergib den Wert als Ausdruck (={{ $('Clean JSON').first().json.config }} – Ausdrücke in normalen Knoten laufen im Hauptprozess und sind nicht betroffen), dann lies ihn von $input im Code-Knoten. Memory bleibt genau wo es ist.

Schreib dann auf, was die Log-Zeile sagt, und ich gebe dir die genaue Umschreibung für deinen Knoten.

@sherazbintahir Die Variable ist nicht Memory — es ist der Node Swap. Ohne Memory hast du den einfachen OpenAI-Node verwendet. Um Memory anzuhängen, musstest du zum AI Agent wechseln, einem LangChain-Cluster-Root, der Sub-Nodes auf die Canvas zieht (Chat Model, Memory, dein search_workwell_memory Tool). Der OpenAI-Node läuft im Task Runner einwandfrei; Agent Sub-Nodes oft nicht.

Warum nur einige Code-Nodes: Seit v2.0 laufen alle Code-Nodes in einem separaten Runner-Prozess.

  • Nutzt nur $input / $json → schmale Payload, sofort. ja (deine Cleaning/Validation-Nodes)
  • Nutzt $('Node') / $node['Node'] / $items() → Runner fordert den gesamten serialisierten Workflow zurück und rekonstruiert ihn, was bedeutet, jeden Node-Typ auf deiner 120-Node-Canvas aufzulösen, Sub-Nodes eingeschlossen. Ein nicht aufzulösender Typ - Request kehrt nie zurück - Hängen bis der 300s Watchdog auslöst. nein (deine Payload Builder — die roten Punkte)

Das Tool Sub-Node kann das allein auch verursachen: #20752 war postgrestool, #20132 Apify/Perplexity — dort hängend sich sogar, obwohl der Agent nie ausgeführt wurde.

Bestätige in 30s — Memory angehängt lassen, einen gefrorenen Node stub:

js

// const cfg = $('Prepare Normal Formatter Evidence').first().json;
const cfg = { test: true };

Läuft sofort → bestätigt.

Beste Behebung zuerst:

  1. Node in den Code-Node zusammenführen, dann $input.all() lesen. Sauberstes bei deinem Maßstab.
  2. Node vorne setzen, Werte als Expressions auflösen: ={{ $('Parse Extraction').first().json.score }} Expressions in normalen Nodes evaluieren im Hauptprozess, also sind sie immun.
  3. Code-Node überspringen — JSON-Body direkt im HTTP Request-Node mit Expressions bauen.

Halte pairedItem: { item: index } auf zurückgegebenen Items, oder nachgelagerte Expressions reintroduzieren das Problem. Memory bleibt in allen drei angehängt.

Hilft nicht: N8N_RUNNERS_TASK_TIMEOUT erhöhen (das Warten ist unbegrenzt), oder N8N_RUNNERS_ENABLED=false (in 2.x ignoriert).

Kannst du die Ausgabe von docker logs -f <n8n-container> | grep -i "unrecognized" posten während du mit dem Agent verbunden läufst? Das zeigt, ob es die Memory oder das Tool ist.