Tenho um fluxo de trabalho que usa um Schedule Trigger e executa várias vezes por dia. Após vários dias funcionando corretamente, o fluxo de trabalho simplesmente para de disparar. Não há execuções com falha nem mensagens de erro nos logs. O fluxo de trabalho permanece ativo, mas as execuções agendadas não iniciam mais.
Durante a solução de problemas, notei que se eu reduzir o número de execuções agendadas por dia, o fluxo de trabalho continua funcionando por mais alguns dias antes de eventualmente parar novamente. Isso me faz pensar que o problema pode estar relacionado ao agendador, modo de fila ou alguma limitação de recursos que se acumula ao longo do tempo.
Alguém já viu fluxos de trabalho com Schedule Trigger pararem silenciosamente em uma implantação Kubernetes executando em modo de fila?
Qual é a mensagem de erro (se houver)?
Não há mensagem de erro. O Schedule Trigger simplesmente para de disparar.
Compartilhe seu fluxo de trabalho
O problema não é específico de um fluxo de trabalho particular. Acontece com fluxos de trabalho que começam com um Schedule Trigger e executam com sucesso até o trigger parar de disparar.
Schedule Trigger → (vários nós)
Compartilhe a saída retornada pelo último nó
Não há saída quando o problema ocorre porque o fluxo de trabalho nunca é iniciado. Quando executa, o fluxo de trabalho é concluído com sucesso.
Informações sobre sua configuração n8n
Versão n8n: Helm chart n8n versão 1.16.39 (me avise se a versão da aplicação real é mais relevante)
Banco de dados: PostgreSQL (externo)
Configuração n8n EXECUTIONS_PROCESS: Modo de fila
Executando n8n via: Kubernetes usando o Community Helm Chart
Sistema operacional: Cluster Kubernetes (nós Linux)
Há um problema documentado (referenciado nas issues do GitHub #30220 e #30256) onde o Schedule Trigger silenciosamente para de disparar após um certo número de execuções (geralmente em torno de 700+ ticks para workflows de alta frequência).
O Sintoma: O workflow permanece “Ativo” na UI, execuções manuais funcionam perfeitamente, mas o disparador automatizado simplesmente para.
A Causa: Um erro de recursão/estouro de pilha ocorre em observable-object.ts durante a lógica de ativação do disparador.
Detalhe Crucial: Este erro não aparece nos logs de Execução do Workflow porque o crash acontece no loop interno do agendador antes de uma execução sequer ser criada. Ele só aparece nos logs de stdout/stderr do container n8n Main.
Outro problema conhecido (#28423) envolvia o Schedule Trigger usando uma verificação de igualdade estrita (===) para determinar se era hora de disparar.
O Sintoma: Se o processo main for reiniciado ou uma mudança de liderança ocorrer exatamente quando um disparador deveria disparar, o timestamp de lastExecution se torna “obsoleto”.
A Causa: Por causa da verificação estrita, o agendador aguardaria o exato próximo tick. Se o estado fosse corrompido ou perdido, o workflow poderia ser silenciosamente bloqueado por dias ou semanas.
A Solução: Isso foi atualizado para uma verificação de “tempo decorrido” (>=) para permitir que o agendador se “auto-recupere” e dispare imediatamente se detectar uma janela perdida.
No modo fila, o Schedule Trigger é possuído exclusivamente pelo processo Main (Líder).
Disparadores Fantasma: Se seu gráfico Helm estiver configurado para permitir mais de uma réplica do processo main (ou se um pod antigo persistir durante uma atualização progressiva), você pode encontrar “disparadores fantasma” ou conflitos de registro no Redis que eventualmente travam o agendador.
Papel de Worker: Se pods de worker acidentalmente estiverem executando o comando n8n start em vez de n8n worker, eles tentarão agir como processos main, competindo pelo agendador e causando comportamento errático.
Algum desses se aplica?
Você pode fazer o seguinte também?
Verifique os Logs do Container (Não os Logs da UI): Inspecione os logs do seu pod n8n main usando kubectl logs <pod-name>. Procure especificamente pela string: RangeError: Maximum call stack size exceeded Se você vir isso, você confirmou o bug observable-object.
Verifique Réplicas do Pod Main: Certifique-se de que sua implantação main está estritamente configurada com replicas: 1. No modo fila, ter múltiplos mains sem uma configuração robusta de eleição de líder geralmente leva à instabilidade do agendador.
Verifique Comandos de Worker: Verifique a seção args ou command dos seus pods de worker. Eles devem estar executando: n8n worker (e NÃO n8n start).
Atualize a Versão do n8n: As correções tanto para o RangeError quanto para o agendador “Auto-recuperável” foram lançadas em atualizações recentes (especificamente abordadas em versões por volta de 2.20.9 e posteriores na branch @next, e retroativamente portadas para a versão estável). Como você está na 1.16.39, você provavelmente está executando uma versão suscetível a esses bugs. Atualizar para o lançamento estável mais recente é a correção primária recomendada.
Vi os logs do pod principal e encontrei muitas mensagens de “Maximum call stack size exceeded”. Percebi que estou alguns meses atrás em termos de versões, vou tentar atualizar para versões mais recentes e ver se isso ajuda.
Bom que você confirmou o ‘Maximum call stack size exceeded’ - esse é o bug do #30220. Uma coisa para verificar novamente em seus valores do Helm antes e depois de fazer upgrade: replicaCount para o deployment principal deve ser exatamente 1. Executar mais de 1 réplica principal causa conflitos de registro do scheduler no Redis que podem reproduzir o mesmo sintoma de parada silenciosa mesmo após fazer upgrade. Workers podem escalar livremente, mas main permanece em 1.
Fico feliz que o grep do log tenha confirmado — uma parede de “Maximum call stack size exceeded” no pod principal é o bug de acúmulo de tick #30220, e corresponde exatamente aos seus próprios indícios: menos execuções/dia = mais tempo para atingir o limite, e um reinício zera o contador. O upgrade é o conserto certo, e a verificação replicaCount: 1 de nguyenthieutoan vale a pena fazer no mesmo passo. Uma pequena coisa enquanto você escolhe para qual versão fazer upgrade: “1.16.39” é a versão do chart do Helm, não a versão do app n8n — elas são numeradas independentemente, então verifique para qual image.tag você está realmente resolvendo e aponte para a versão de app estável mais recente, não um número de chart.
A parte que eu sinalizaria porque sobrevive ao upgrade: essa classe de falha é invisível ao n8n por design. Nenhuma execução é criada, então o Error Trigger nunca dispara — não há nada a que anexar um erro. É por isso que rodou silenciosamente por dias. Mesmo totalmente corrigido, um scheduler que “simplesmente para, Ativo na UI, sem erro” é algo que você sempre aprenderá sobre tarde, quando um humano notar dados faltando. O conserto duradouro é um dead-man’s-switch externo: faça o workflow agendado enviar um heartbeat a cada execução bem-sucedida (uma chave Redis com TTL, uma linha com timestamp, ou um ping para um monitor estilo healthchecks), e faça algo independente do n8n alertar quando o heartbeat fica obsoleto. Isso transforma “parou silenciosamente por dias” em “alertado em minutos”, seja qual for a causa raiz na próxima vez.
Se o upgrade não curar completamente — você confirmou o RangeError, mas se ainda ficar silencioso em uma versão corrigida com replicas: 1 e workers realmente executando n8n worker — essa é a branch específica da implantação, e fico feliz em ajudá-lo a investigar aqui.
Um acompanhamento antes de encerrar esta conversa, porque há um detalhe específico do Kubernetes que os ajustes acima não cobrem, e isso explica por que essa falha é tão silenciosa no seu cluster em particular.
Sua sonda de vivacidade não consegue ver essa falha. O endpoint de saúde do n8n responde do servidor web, e o servidor web está bem enquanto o loop do agendador está travado, então o Kubernetes continua relatando um pod saudável e nunca o reinicia. É por isso que a interrupção dura dias: o único mecanismo integrado para reiniciar um pod quebrado está lendo um sinal que não exercita o componente quebrado. A saúde do processo e a saúde do agendador são coisas diferentes, e cada sonda que você tem atualmente mede a primeira.
Como um reinício restaura confiávelmente o gatilho, você pode fechar a lacuna enquanto planeja a atualização com um canário: um fluxo de trabalho agendado trivial que não faz nada além de escrever um carimbo de data/hora em algum lugar barato a cada poucos minutos, uma chave Redis, uma linha do Postgres, ou um ping para um monitor gratuito como o Healthchecks.io. Quando o carimbo de data/hora fica obsoleto, o agendador está travado independentemente do que o endpoint de saúde diz. Se quiser que seja totalmente automático, um pequeno CronJob que verifica a atualização do canário e faz um reinício de rollout da implantação principal quando fica obsoleto transforma uma interrupção de vários dias em alguns minutos de falha, o que é um contorno aceitável para um bug que apenas a atualização realmente corrige.
Duas verificações que valem a pena fazer no próximo travamento, antes de reiniciar, para que a decisão de atualização seja fundamentada. Pegue os logs do pod principal e procure por RangeError: Maximum call stack size exceeded, como kjooleng disse. E faça a matemática dos ticks: sua própria observação de que menos execuções por dia atrasam a falha é exatamente o que um bug de limite de ticks prevê, então se o número de execuções por dia multiplicado pelos dias até a falha resultar em uma constante aproximadamente igual entre seus incidentes, você tem a confirmação sem nem mesmo esperar pela linha de log.