Depuração de Workflows n8n
Corrija workflows n8n como um engenheiro sênior — sistematicamente, não por tentativa e erro.
Triagem: identifique primeiro a classe da falha
Pergunte ao usuário (ou deduza pelo texto do erro) qual classe:
| Classe | Sintoma | Causas raiz comuns |
|---|---|---|
| Erro de expressão | Cannot read property X of undefined, selo vermelho no nó | Sintaxe de expressão errada, falta do prefixo =, acesso a campos indefinidos |
| Incompatibilidade de tipo | Expected string, got array, estranheza downstream | Confusão entre Item Lists e item único, formato de saída de Split In Batches |
| Silencioso vazio | Workflow executa verde, mas sem saída/efeito colateral | Condição de filtro errada, dados fixos desatualizados, escopo de credencial |
| Falha de autenticação | 401, 403, Invalid API key | Credencial errada selecionada, token expirado, refresh OAuth não configurado |
| Limite de taxa | 429 intermitente, funciona manualmente, falha em lote | Sem backoff, lote muito grande, credencial compartilhada entre workflows |
| Sub-workflow | Execute Workflow retorna nada ou erros | Parâmetros não passados, valor de retorno não definido, ID de workflow errado |
Erros de expressão
A maior armadilha: ={{ $json.field }} vs {{ $json.field }}. O = inicial torna o campo uma expressão. Sem ele, a string literal {{ $json.field }} é enviada.
Verifique:
- Clique no campo — ele mostra o alternador de "expressão" (ícone fx) destacado? Se não, está no modo literal.
- Na visualização JSON do código, o valor deve começar com
=:"value": "={{ $json.id }}"
Acessando caminhos indefinidos: $json.customer.email lança erro se customer for nulo. Use encadeamento opcional: $json.customer?.email ?? 'unknown'.
Referenciando nós anteriores: Use $('Node Name').item.json.field, NÃO $node['Node Name'].json.field (obsoleto). Cite o nome exato do nó incluindo espaços.
Padrões comuns de expressão:
// Acesso a array
{{ $json.items[0].name }}
{{ $json.items?.[0]?.name ?? 'empty' }}
// Saída de nó anterior
{{ $('Webhook').item.json.body.email }}
// Todos os itens do nó anterior (para loops)
{{ $('Split In Batches').all().map(i => i.json.id) }}
// Condicional
{{ $json.amount > 100 ? 'high' : 'low' }}
// Formatação de data (n8n usa Luxon)
{{ $now.toISO() }}
{{ $now.minus({ days: 7 }).toFormat('yyyy-MM-dd') }}
// Variáveis de ambiente (self-hosted)
{{ $env.MY_SECRET }}
Diagnóstico de incompatibilidade de tipo
O n8n passa dados como um array de itens, cada um com { json: {...}, binary: {...} }. Muitos bugs vêm de tratar um único item como array ou vice-versa.
Rotina de inspeção:
- Abra a visualização de entrada do nó com falha (painel esquerdo)
- Verifique: é UM item com um array dentro (
{ json: { list: [...] } }), ou MÚLTIPLOS itens ([ { json: {} }, { json: {} } ])? - Eles exigem tratamento diferente:
- Array dentro de um item → use
Item Lists→ "Split Out Items" para expandir - Já múltiplos itens → opere por item
- Array dentro de um item → use
Split In Batches gera formatos diferentes nas saídas principal vs "done" — a saída principal é um lote, a saída "done" está vazia. Conecte adequadamente.
Silencioso vazio — o pior tipo
Workflow mostra marcas verdes, mas nada aconteceu downstream. Ordem de diagnóstico:
- Verifique a retenção de dados de execução. Configurações → "Save data successful executions" deve ser "All" durante a depuração, não "None".
- Inspecione a saída de cada nó. Clique em cada nó → painel "Output". Encontre o primeiro que está vazio quando você esperava dados.
- Dados fixos? Se um nó tem um ícone de alfinete, ele está retornando dados de teste fixos, NÃO dados reais. Clique com o botão direito → Unpin Data.
- Condições de filtro / IF. Um
IFque avalia falso silenciosamente pula o ramo. Verifique o valor da condição em tempo de execução. - Escopo da credencial. Credenciais OAuth do Google/Microsoft geralmente têm escopos limitados. Uma credencial "Google Sheets" não permite ler Gmail. Reautentique com os escopos corretos.
Falhas de autenticação
- 401 em um workflow que funcionava antes → token expirado. Reautentique a credencial.
- 401 imediatamente em um novo workflow → tipo de credencial errado. Ex.: "Header Auth" vs "OAuth2" — verifique a documentação da API.
- 403 com token válido → escopo ausente OU conta errada. Credenciais OAuth são por conta; confirme que você autenticou com a conta Google/Meta correta.
Específico para n8n self-hosted: se uma credencial parar de funcionar repentinamente após uma reinicialização do contêiner, verifique se a chave de criptografia (variável de ambiente N8N_ENCRYPTION_KEY) foi persistida. Perdê-la = todas as credenciais corrompidas.
Falhas por limite de taxa
Sintoma: funciona em 10 itens, falha em 100. Clássico.
Padrão de correção:
- Envolva a chamada de API em
Split In BatchescombatchSizecorrespondente ao limite por segundo do fornecedor - Adicione um nó
Waitentre os lotes:waitBetweenBatches: ceil(60000 / requests_per_minute) - Defina
retry.maxTries: 3comretry.waitBetweenTries: 5000no nó HTTP Request - Verifique os cabeçalhos de resposta (
X-RateLimit-Remaining,Retry-After) e faça backoff dinamicamente via um nóCode
Para workflows acionados por cron que acessam o mesmo fornecedor a partir de múltiplos jobs cron, centralize a chamada de API em UM sub-workflow com um padrão de semáforo (linha MySQL como bloqueio).
Falhas de sub-workflow
Execute Workflow retorna null ou indefinido na maioria das vezes porque:
- O pai não passou dados. Verifique "Workflow Inputs" no nó Execute Workflow — deve referenciar
{{ $json }}ou campos explícitos. - O filho não definiu saída. A saída do ÚLTIMO nó no sub-workflow se torna o valor de retorno. Se o último nó for uma inserção
MySQLque não retorna nada, o pai não recebe nada. Adicione um nóSetfinal que constrói o payload de retorno. - ID de workflow errado. O sub-workflow foi excluído e recriado → novo ID → referência desatualizada.
Lendo logs de execução do n8n
O log de execução mostra entrada e saída por nó. Padrão de depuração:
- Encontre o primeiro nó com falha (vermelho).
- Observe a entrada DELE (esquerda). A forma é a que você esperava?
- Se a entrada estiver errada, o bug está ACIMA — rastreie de volta.
- Se a entrada estiver correta, mas a saída estiver errada/com erro, o bug está NESTE NÓ — verifique os parâmetros.
A maioria dos bugs são problemas de forma upstream disfarçados de erros downstream. A mensagem de erro mente sobre onde o bug está.
Checklist de correção rápida para casos comuns
- Expressão não está interpolando → adicione
=no início - Nó diz "No items to process" → o IF upstream está filtrando tudo, ou o nó anterior retornou vazio
- Anexação do Google Sheets inserindo duplicatas → sem restrição única, adicione verificação de idempotência (veja a habilidade
mysql-checkpointing) - LLM retorna JSON lixo → mude de HTTP bruto para
Information Extractorcom esquema (veja a habilidadechain-llm-pattern) - Webhook expira → mova o trabalho pesado para trás de
Respond to Webhook(responda primeiro, processe de forma assíncrona)
Quando estiver travado
Peça ao usuário:
- Captura de tela do log de execução (o painel com borda vermelha)
- A mensagem de erro exata (copie e cole do nó)
- Os parâmetros do nó (guia de configurações, visualização JSON se possível)
- Se isso já funcionou antes (regressão vs novo bug)
Não adivinhe sem essas informações. Erros do n8n são específicos — suposições vagas perdem tempo.