Estou na versão 2.33.4 auto-hospedada. Nós de código que usam require('xlsx') falham com Cannot find module 'xlsx'. Isso funcionava antes de minha última atualização, que fiz por volta de 27–28 de junho de 2026 — estou usando a tag n8nio/n8n:latest, então não tenho mais o número da versão anterior e a imagem antiga desapareceu. NODE_FUNCTION_ALLOW_EXTERNAL=xlsx sempre foi definido, e estava funcionando antes da atualização. Essa variável de ambiente é anterior à atualização por muito tempo, não mudou durante ela, e ainda está definida agora. A única coisa que mudou é a versão do n8n.
Qual é a mensagem de erro (se houver)?
Cannot find module 'xlsx'
Compartilhe seu workflow
Compartilhe a saída retornada pelo último nó
{"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\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/cjs/loader: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)"]}}
Informações sobre sua configuração de n8n
Versão do n8n: 2.33.4
Banco de dados (padrão: SQLite): PostgreSQL
Configuração EXECUTIONS_PROCESS do n8n (padrão: own, main): main
Executando n8n via (Docker, npm, n8n cloud, desktop app): Docker
De acordo com a documentação abaixo, quando os executores de tarefas estão ativos, você deve configurar módulos externos usando substituições de executor específicas.
Adicione as seguintes variáveis de ambiente ao seu docker-compose.yml (ou onde quer que suas configurações de ambiente sejam definidas) e recrie o container:
Alternadamente, se você está executando executores de tarefas por meio de seu próprio serviço de container separado no Docker, as variáveis de definição de módulo externo devem ser aplicadas diretamente ao ambiente do container do serviço do executor de tarefas em vez do container backend principal do n8n.
por favor usar a versão estável n8n 2.31.4 — Stable
se mesmo assim apresentar erro, compartilhar para melhor análise.
complementando: além de aplicar as variáveis no ambiente do task runner, eu evitaria usar n8nio/n8n:latest nesse cenário e fixaria uma versão específica da imagem. Assim, se uma atualização alterar novamente o comportamento dos runners ou das dependências, fica muito mais fácil identificar exatamente em qual versão a mudança ocorreu e fazer rollback.
services:
n8n:
image: n8nio/n8n:latest
environment:
- NODE_FUNCTION_ALLOW_EXTERNAL=xlsx
- NODE_PATH=/usr/local/lib/node_modules
# ... suas outras variáveis
# Se você não tiver um Dockerfile personalizado, pode ser necessário instalá-lo ao iniciar:
command: /bin/sh -c "npm install -g xlsx && n8n"
Não garantimos a disponibilidade de nenhum pacote externo na imagem do n8n. Mesmo que possa ter funcionado antes, isso é por coincidência, não por design.
Como mencionado nas mensagens acima, você precisa instalar o pacote por conta própria. Você pode fazer isso de duas formas:
construindo uma imagem personalizada estendendo a imagem oficial do docker do n8n, como mencionado em nossa documentação
executando um comando de configuração que instala o pacote antes de iniciar o n8n, como foi mencionado acima
Eu sei que isso pode ser um pouco complicado. A longo prazo, estamos planejando fazer alterações no nó de código para que você possa escolher quais dependências deseja usar diretamente do workflow, e o n8n lidará com a instalação delas em segundo plano.
1.Crie um arquivo chamado Dockerfile no mesmo diretório do seu docker-compose.yml:
FROM n8nio/n8n:latest
USER root
# Instale o módulo globalmente
RUN npm install -g xlsx
# Certifique-se de que o caminho do Node está definido para todos os processos
ENV NODE_PATH=/usr/local/lib/node_modules
USER node
2.Modifique seu docker-compose.yml para compilar este arquivo em vez de extrair a imagem bruta:
services:
n8n:
# Remova a linha 'image' ou comente-a
# image: n8nio/n8n:latest
build: .
environment:
- NODE_FUNCTION_ALLOW_EXTERNAL=xlsx
- NODE_PATH=/usr/local/lib/node_modules
# ... suas outras variáveis
# REMOVA a linha 'command' que você adicionou anteriormente
3.Implante: Execute os seguintes comandos para reconstruir e reiniciar:
Aqui está a segunda correção que pode resolver o problema.
Altere o Nó de Código para “n8n-native” JavaScript
Se você absolutamente precisar usar JavaScript, não precisa mais fazer require('xlsx'). As versões modernas do n8n fornecem uma variável auxiliar global nativa chamada $binary ou métodos integrados para lidar com dados de arquivo sem importar pacotes externos.
Você pode modificar o código para utilizar os recursos integrados da interface auxiliar visual ou usar:
javascript
// Exemplo usando referências de dados internas n8n integradas sem 'require'
const binaryData = await this.helpers.getBinaryDataBuffer(0, 'data');
// Use mapeamento de itens de array nativo do n8n em vez de strings de decodificação xlsx bruta
Oi @jburns
Sobre a questão do rollback, alterar a tag de volta para 2.31.4 não é uma reversão limpa. 2.33.4 já aplicou suas migrações ao seu Postgres e essas apenas avançam, então o binário mais antigo iniciaria contra um schema para o qual nunca foi compilado. A forma suportada de retroceder é restaurar o snapshot do banco de dados tirado antes da atualização, e como você atualizou de uma imagem que você não tem mais, manter-se em 2.33.4 com o pacote instalado em uma imagem personalizada é o caminho de menor risco.
Veja isto:
NODE_FUNCTION_ALLOW_EXTERNAL=xlsx apenas coloca um pacote na lista de permissões. Isso não o instala. Seu rastreamento de pilha atinge o resolvedor do executor de tarefas e termina em Cannot find module 'xlsx', portanto, este é um problema de disponibilidade de módulo, não um problema de lista de permissões.
A configuração proposta N8N_ENFORCE_SETTINGS_FILE_FOR_RUNNERS não instalará xlsx. O comando de inicialização também falha porque a imagem n8n atual não tem /bin/sh. Eu não faria o downgrade da instância ativa como próximo teste.
Primeiro, fixe a imagem n8n atual e faça backup do banco de dados mais do volume de dados n8n. Teste qualquer downgrade em um banco de dados clonado e volume, nunca o par ativo. Uma solução durável em produção é o modo executor externo com uma imagem personalizada n8nio/runners que instala xlsx no executor JavaScript e a coloca na lista de permissões na configuração do executor. Mantenha a imagem do executor na mesma versão do n8n.
Se você quiser permanecer com um contêiner e executores internos, a documentação atual não fornece um caminho de imagem de dependência extra suportado. Use um nó de planilha integrado ou mova esta análise para um nó personalizado privado em vez de depender de um pacote que acontecia estar presente em latest.
Muitíssimo obrigado por isso, a rota do executor externo foi exatamente a decisão correta, e fico feliz por não ter seguido o caminho do downgrade.
O que acabei fazendo:
Fixei a imagem n8n e arquivei meu volume n8n_data com n8n parado, para que SQLite não estivesse no meio de uma escrita: docker run --rm -v n8n_data:/data:ro -v "$PWD":/backup alpine tar czf /backup/n8n_data-$(date +%F).tar.gz -C /data .
Passei a instância principal para N8N_RUNNERS_MODE=external com N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0, e adicionei um sidecar n8nio/runners na mesma tag de versão
Construí a imagem de executores personalizada com pnpm add xlsx em /opt/runners/task-runner-javascript, e adicionei xlsx ao NODE_FUNCTION_ALLOW_EXTERNAL no bloco env-overrides de n8n-task-runners.json. Vale sinalizar que NODE_FUNCTION_ALLOW_EXTERNAL no próprio container n8n é ignorado no modo externo — tem que estar na configuração do launcher.
Uma armadilha para qualquer um estendendo a imagem: a construção falhou com ERR_PNPM_UNEXPECTED_STORE. Corepack puxa o pnpm mais recente (11.x, store v11) enquanto o node_modules da imagem base está vinculado ao store v10, e pnpm recusa misturar versões principais. Resolvi fixando antes da instalação:
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
RUN corepack prepare pnpm@10.34.5 --activate
Não siga o próprio conselho do erro para executar pnpm install — não há lockfile na imagem, então redefine toda a árvore do executor.
Epílogo divertido: com o executor funcionando, require('xlsx') retornou bem, mas o nó de Código ainda lançou um “Unknown error” vazio com errorDetails vazio. Descobriu-se que a propriedade binária era chamada File, não data, e getBinaryDataBuffer lança um objeto que não é Error em um nome de propriedade ruim, então nenhuma mensagem sobrevive ao limite do executor. Ler a chave de Object.keys($input.first().binary) resolveu.
Muito obrigado novamente! A configuração é mais robusta do que o que eu tinha antes, então valeu a pena fazer de qualquer forma.