Code-Node kann externes Modul „xlsx

Beschreibe das Problem/den Fehler/die Frage

Ich bin auf Version 2.33.4 selbst gehostet. Code-Knoten, die require('xlsx') nutzen, schlagen fehl mit Cannot find module 'xlsx'. Das funktionierte vor meinem letzten Update, das ich um den 27.–28. Juni 2026 gemacht habe – ich verwende das Tag n8nio/n8n:latest, daher habe ich die vorherige Versionsnummer nicht mehr und das alte Image ist weg.
NODE_FUNCTION_ALLOW_EXTERNAL=xlsx war schon immer gesetzt und funktionierte vor dem Update. Diese Umgebungsvariable existiert schon lange vor dem Update, hat sich nicht während des Updates geändert und ist immer noch gesetzt. Das Einzige, das sich geändert hat, ist die n8n-Version.

Wie lautet die Fehlermeldung (falls vorhanden)?

Cannot find module 'xlsx'

Bitte teile deinen Workflow

Teile die Ausgabe des letzten Knotens

{"errorMessage":"Cannot find module 'xlsx'\nRequire stack:\n- /usr/local/lib/node_modules/n8n/node_modules/.pnpm/+task-runner@file+packages++task-runner_@opentelemetryopentelemet@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8cy+api@1.9.0_@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8c/node_modules//task-runner/dist/js-task-runner/require-resolver.js\n- /usr/local/lib/node_modules/n8n/no@opentelemetrye_modules/.@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8cnpm/+task-runner@file+packages++task-runner_@opentelemetry+api@1.9.0_@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8c/node_modules//task-runner/dist/js-task-@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8cunner/js-task-@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8cunner.js\n- /usr/local/lib/node_modules/n8n/node_modules/.pnpm/+task-runner@file+packages++task-runner_@opentelemetry+api@1.9.0_@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8c/node_modules//task-runner/dist/start.js","errorDetails":{},"n8nDetails":{"n8nVersion":"2.33.4 (Cloud)","binaryDataMode":"fi@opentelemetryesystem","@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8ctackTrace":["Error: Cannot find module 'xlsx'","Require stack:","- /usr/local/lib/node_modules/n8n/node_modules/.pnpm/+task-runner@file+packages++task-runner_@o@opentelemetryentelemetry@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8capi@1.9.0_@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8c/node_modules//task-runner/dist/js-task-runner/require-resolver.js","- /usr/local/lib/node_modules/n8n/no@opentelemetrye_modules/.@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8cnpm/+task-runner@file+packages++task-runner_@opentelemetry+api@1.9.0_@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8c/node_modules//task-runner/dist/js-task-runner/js-task-runner.js","- /usr/local/lib/node_modules/n8n/node_modules/.pnpm/+task-runner@file+packages++task-runner_@opentelemetry+api@1.9.0_@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8c/node_modules//task-runner/dist/start.js","    at Module.resolveFilename (node:internal/modules/cjs/loader:1517:15)","    at wrapResolveFilename (node:internal/modules/cjs/loader:1071:27)","    at defaultResolveImplForCJSLoading (node:internal/modules/cjs/loader:1095:10)","    at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1122:12)"," @opentelemetry  at Module.load (node:internal/modules/cjs/loader:1294:5)","    at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)","    at Module.require (node:internal/modules/cjs/loader:1617:12)","    at require (node:internal/modules/helpers:153:16)","    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/+task-runner@file+packages++task-runner@opentelemetry+api@1.9.0@opentelemetry_f4c4f0962cb44afa934cbd57e3ebca8c/node_modules//task-runner/dist/js-task-runner/require-resolver.js:68:26","    at VmCodeWrapper (evalmachine.:2:46)"]}}

Informationen zu deinem n8n-Setup

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

Hallo @jburns, während du auf eine Antwort wartest, könnten dir folgende Dinge helfen:

Empfohlene Ressourcen

Automatisch auf deine Frage abgestimmt.

Dokumentation:

Forum:

@ThinkBot, @jcuypers, @tamy.santos - ihr habt bei ähnlichen Problemen schon geholfen, könnt ihr euch das anschauen?

Automatisch vorgeschlagen vom Community-Bot von n8n. Das ist ein Pilotprojekt - geben Sie bitte hier Feedback.

Hallo @jburns Willkommen!

Aktualisiere deine Umgebungsvariablen

Laut der folgenden Dokumentation musst du externe Module mit spezifischen Runner-Overrides konfigurieren, wenn Task Runner aktiv sind.

Enable modules in Code node | Deploy | n8n Docs..

Füge die folgenden Umgebungsvariablen zu deiner docker-compose.yml (oder wo immer deine Umgebungskonfigurationen definiert sind) hinzu und erstelle den Container neu:

yaml

environment:
  - NODE_FUNCTION_ALLOW_EXTERNAL=xlsx
  - N8N_ENFORCE_SETTINGS_FILE_FOR_RUNNERS=true

Code mit Vorsicht verwenden.

Alternativ, falls du Task Runner über einen eigenen separaten Container-Dienst in Docker ausführst, müssen die Variablen zur Definition des externen Moduls direkt auf die Task-Runner-Service-Container-Umgebung angewendet werden, anstatt auf den Haupt-n8n-Backend-Container.

Guten Morgen @jburns

bitte verwenden Sie die stabile Version n8n 2.31.4 — Stable
falls dennoch ein Fehler auftritt, teilen Sie ihn für eine bessere Analyse mit.

ergänzend: zusätzlich zum Anwenden der Variablen in der Umgebung des Task Runners würde ich vermeiden, n8nio/n8n:latest in diesem Szenario zu verwenden, und würde eine spezifische Version des Images festlegen. Auf diese Weise können Sie, falls eine Aktualisierung das Verhalten der Runner oder der Abhängigkeiten erneut ändert, genau identifizieren, in welcher Version die Änderung aufgetreten ist, und ein Rollback durchführen.

Danke, dass du uns Bescheid gegeben hast. Wir haben CAT-4010 als internes Entwicklungs-Ticket erstellt, um uns damit zu befassen.

Hi @jburns

Aktualisiere deine Compose-Datei auf etwa folgendes

services:
  n8n:
    image: n8nio/n8n:latest
    environment:
      - NODE_FUNCTION_ALLOW_EXTERNAL=xlsx
      - NODE_PATH=/usr/local/lib/node_modules
      # ... deine anderen Variablen
    # Wenn du kein Custom Dockerfile hast, musst du es möglicherweise beim Start installieren:
    command: /bin/sh -c "npm install -g xlsx && n8n"

Hilft dir das weiter?

Danke für deine Antwort. Leider hat das nicht funktioniert. Ich habe keine externen Task Runner, nur einen einzelnen n8n-Container.

Danke für deine Antwort! Die Lösung hat nicht funktioniert. Sie schlägt fehl mit

Error: Command "/bin/sh" not found

Außerdem erinnere ich mich nicht, xlsx vorher installieren zu müssen. Wird es nicht bereits von nativen Nodes wie Extract from File oder Convert to File verwendet?

Hallo Tamy, danke! Ich habe Angst, von 2.33.4 auf 2.31.4 zurückzurollen, ist das sicher für meine Instanz?

Hi @jburns

Wir garantieren nicht die Verfügbarkeit externer Pakete im n8n-Image. Auch wenn es zuvor funktioniert haben könnte, ist das reiner Zufall und nicht beabsichtigt.

Wie in den obigen Nachrichten erwähnt, musst du das Paket selbst installieren. Das kannst du auf zwei Wegen tun:

  1. Indem du ein benutzerdefiniertes Image erstellst, das das offizielle n8n-Docker-Image erweitert, wie in unserer Dokumentation erwähnt
  2. Indem du einen Setup-Befehl ausführst, der das Paket installiert, bevor n8n gestartet wird, wie oben erwähnt

Ich weiß, dass das etwas knifflig sein kann. Langfristig planen wir Änderungen am Code-Node, damit du direkt aus dem Workflow wählen kannst, welche Abhängigkeiten du verwenden möchtest, und n8n kümmert sich im Hintergrund um deren Installation.

1.Erstelle eine Datei namens Dockerfile im gleichen Verzeichnis wie deine docker-compose.yml:

FROM n8nio/n8n:latest

USER root

# Installiere das Modul global
RUN npm install -g xlsx

# Stelle sicher, dass der Node-Pfad für alle Prozesse gesetzt ist
ENV NODE_PATH=/usr/local/lib/node_modules

USER node

2.Ändere deine docker-compose.yml, um diese Datei zu bauen, statt das rohe Image zu ziehen:

services:
  n8n:
    # Entferne die „image

@jburns

Hier ist die zweite Lösung, die das Problem beheben könnte.

**Wechseln Sie den Code Node zu „n8n-native

Hallo @jburns
Zur Frage des Rollbacks: Das Ändern des Tags zurück auf 2.31.4 ist kein sauberes Revert. 2.33.4 hat bereits seine Migrationen auf deinem Postgres durchgeführt, und diese laufen nur vorwärts, sodass die ältere Binärdatei gegen ein Schema starten würde, für das sie nie gebaut wurde. Der unterstützte Weg zurück ist die Wiederherstellung des Datenbank-Snapshots, der vor dem Update erstellt wurde. Da du von einem Image aktualisiert hast, das du nicht mehr hast, ist das Bleiben bei 2.33.4 mit dem Paket, das in ein benutzerdefiniertes Image installiert ist, der Weg mit geringerem Risiko.
Siehe hier:

NODE_FUNCTION_ALLOW_EXTERNAL=xlsx allowlisten nur ein Paket. Es wird nicht installiert. Deine Stack-Trace erreicht den Task-Runner-Resolver und endet bei Cannot find module 'xlsx', also ist dies ein Modulverfügbarkeitsproblem, kein Allowlist-Problem.

Die vorgeschlagene N8N_ENFORCE_SETTINGS_FILE_FOR_RUNNERS-Einstellung wird xlsx nicht installieren. Der Startup-Befehl schlägt auch fehl, weil das aktuelle n8n-Image kein /bin/sh hat. Ich würde die Live-Instanz nicht als nächsten Test downgraden.

Pinne zunächst das aktuelle n8n-Image und sichere die Datenbank sowie das n8n-Daten-Volume. Teste alle Downgrades gegen eine geklonte Datenbank und ein geklontes Volume, niemals gegen das Live-Paar. Ein dauerhafter Produktions-Fix ist der externe Runner-Modus mit einem benutzerdefinierten n8nio/runners-Image, das xlsx unter dem JavaScript-Runner installiert und es in der Runner-Konfiguration allowlisten. Halte das Runner-Image auf der gleichen n8n-Version.

Wenn du bei einem Container mit internen Runnern bleiben möchtest, bietet die aktuelle Dokumentation keinen unterstützten Pfad für ein Extra-Dependency-Image. Verwende einen integrierten Spreadsheet-Node oder verschiebe dieses Parsing in einen privaten Custom-Node, anstatt dich auf ein Paket zu verlassen, das zufällig in latest vorhanden war.

Vielen Dank dafür, die externe Runner-Route war genau der richtige Weg, und ich bin froh, dass ich nicht den Downgrade-Pfad gegangen bin.

Das habe ich letztendlich getan:

  1. Pinnte das n8n-Image und archivierte mein n8n_data-Volume mit gestopptem n8n, sodass SQLite nicht mitten im Schreiben war:
    docker run --rm -v n8n_data:/data:ro -v "$PWD":/backup alpine tar czf /backup/n8n_data-$(date +%F).tar.gz -C /data .
  2. Schaltete die Hauptinstanz auf N8N_RUNNERS_MODE=external mit N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0 um und fügte einen n8nio/runners-Sidecar in derselben Versionierung hinzu
  3. Erstellte das benutzerdefinierte Runners-Image mit pnpm add xlsx unter /opt/runners/task-runner-javascript und fügte xlsx zu NODE_FUNCTION_ALLOW_EXTERNAL im env-overrides-Block von n8n-task-runners.json hinzu. Es ist erwähnenswert, dass NODE_FUNCTION_ALLOW_EXTERNAL im n8n-Container selbst im externen Modus ignoriert wird — es muss in der Launcher-Konfiguration sein.

Eine Tücke für alle anderen, die das Image erweitern: Der Build schlug mit ERR_PNPM_UNEXPECTED_STORE fehl. Corepack ruft pnpm latest (11.x, Store v11) ab, während das Basis-Image node_modules gegen Store v10 verlinkt ist, und pnpm weigert sich, Majors zu mischen. Behoben durch Pinning vor der Installation:

ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
RUN corepack prepare pnpm@10.34.5 --activate

Folge nicht dem Rat des Fehlers selbst, pnpm install auszuführen — es gibt keine Lockdatei im Image, also wird der gesamte Runner-Baum neu aufgelöst.

Amüsanter Epilog: Mit dem funktionierenden Runner gab require('xlsx') korrekt zurück, aber der Code-Node warf immer noch einen bloßen „Unknown error

Schön, dass es funktioniert hat, und danke, dass du die Details im Thread dokumentiert hast. Deine zwei Hinweise sind für jeden wertvoll, der später hier vorbeischaut. Im externen Modus ist die Allowlist in n8n-task-runners.json entscheidend, und die Variable im Hauptcontainer wird ignoriert. Der ERR_PNPM_UNEXPECTED_STORE-Fehler ist die Store-Major-Versionsinkompatibilität, die du diagnostiziert hast. Das Pinnen von pnpm mit corepack prepare vor der Installation ist also die richtige Lösung, da der Runner-Tree des Basis-Images gegen Store v10 gelinkt ist.

Das leere errorDetails verdient es, verstanden zu werden, statt nur daran herumzudoktern. getBinaryDataBuffer wirft ein einfaches Objekt statt eines Fehlers, wenn der Eigenschaftsname falsch ist, sodass nichts Sinnvolles die Runner-Grenze überquert und du nur eine generische „Unknown error