cleancontext.blog
post 03 · n8nRead in English

A mesma chave, escrita à mão 15 vezes, quebrou um agente

Achado em staging: uma trava que devia sumir quando a conversa seguia nunca sumia, porque duas fórmulas diferentes montavam a mesma chave.

resumo

Em staging, um agente meu parou de responder sem erro visível. A causa: uma trava de timeout que devia ser removida quando a conversa seguia, e não era, porque o node que cria a chave e o node que apaga usam duas fórmulas diferentes para montar o mesmo identificador. Fui ver quantos outros lugares do workflow montavam essa mesma família de chave à mão: mais de 15 nodes diferentes, cada um com sua própria interpolação.

Sem tempo pro post inteiro?

Manda o link pro Claude ler

Abre uma conversa nova no Claude.ai já com o link deste post — ele lê, resume os pontos principais e você continua perguntando por lá.

Em staging, um workflow meu parou de responder no meio do teste. Sem erro visível no n8n, sem exceção nos logs — o agente simplesmente ficou mudo. A causa: uma trava de timeout que devia ser removida quando a conversa seguia, e não era.

Fui atrás da chave que controla essa trava: Helena_{{ ... }}_timeout. Achei o node que cria a trava (set, com TTL de 24h) e o node que devia apagar (delete). Duas construções diferentes da mesma chave:

  • criar:Helena_{{ contact_inbox.source_id }}_timeout
  • apagar:Helena_{{ message.phone.replace('+','') }}_timeout

Quando source_id e o telefone sem + não são o mesmo valor, o delete nunca acerta a chave que o set criou. A trava fica lá até o TTL vencer sozinho. Achei o problema procurando por _timeout dentro do JSON — ninguém tinha comparado essas duas strings lado a lado antes.

Fui ver quantos outros lugares do workflow montavam essa mesma família de chave (Helena_{{ telefone }}, usada como identificador de sessão pra memória, buffer de mensagem e histórico) e não foi 2. Foi mais de 15 nodes diferentes, cada um com sua própria interpolação, cada um dependendo de eu lembrar de manter a mesma fórmula em todos.

Por que isso não é falta de atenção

O workflow tinha guardrails de prompt injection, validação de CNPJ, classificação de motivo de handoff — bastante cuidado investido no que a IA faz. Mas a chave que amarra tudo isso à mesma conversa era texto solto, copiado e colado em cada node que precisava dela. Não existia um lugar único que definisse “a sessão desse cliente é X” — existiam 15 lugares que concordavam, até o dia em que um deles não concordou mais.

É o mesmo problema de credencial duplicada que já resolvi com o Sincronizador de Credenciais, só que em variável em vez de credencial: um valor que devia ter uma única fonte da verdade acaba hardcoded em cada node que precisa dele, e divergir custa caro — nesse caso, um agente mudo. Achado em staging, antes de chegar no cliente, mas só porque eu estava testando esse trecho específico naquele momento. Numa parte menos observada do fluxo, o mesmo bug passaria despercebido.

O que a ferramenta faz

Construí o Normalizador de Variáveis pra achar esse padrão antes que ele vire incidente, direto no navegador.

  • 1.Cola o JSON exportado do workflow.
  • 2.A ferramenta varre todos os nodes procurando o mesmo valor (string, número, expressão n8n) repetido em parâmetros diferentes — não só valor idêntico, mas também construções que deveriam ser idênticas e não são (ex: duas expressões que montam a mesma chave lógica com fontes de dado diferentes).
  • 3.Mostra cada grupo de repetição: o valor, quantos nodes usam, e — quando a interpolação diverge entre ocorrências do “mesmo” valor — sinaliza como suspeito em vez de silenciar.
  • 4.Sugere onde centralizar: um node Set logo após a entrada do fluxo, segurando o valor uma vez, com todo o resto do workflow lendo dali.

Nada sai do navegador. O parse e a varredura rodam no cliente.

Rodei a ferramenta contra o próprio workflow que gerou este post: 36 grupos de valor idêntico repetido em 2+ nodes, e 4 divergências de fórmula — incluindo, na primeira posição, exatamente o par source_id vs. phone do incidente.

O que fica

Repetir um valor em dois nodes é inofensivo até ele parar de ser o mesmo valor. A ferramenta não impede alguém de escrever a mesma fórmula duas vezes — impede que a segunda cópia divirja da primeira sem ninguém notar.

Perguntas

Porque não existe um lugar único que define o valor — existem N lugares que precisam concordar entre si. Cada node que monta a chave de novo é uma chance de divergência: se um deles usa uma fonte de dado ligeiramente diferente (ex: outro campo do payload), a chave que ele gera deixa de bater com as demais, e tudo que depende dela (memória, buffer, trava) para de funcionar silenciosamente.
Porque teste manual só cobre o que alguém decide observar naquele momento. Se a divergência está numa trava de timeout que só é acionada em certas condições, ela pode nunca aparecer nos casos que o desenvolvedor testou por acaso — e só aparecer quando o cenário específico ocorrer em produção.
Além de sinalizar o mesmo valor hardcoded em vários nodes, a ferramenta sinaliza quando duas expressões deveriam montar o mesmo valor lógico (a mesma chave, o mesmo identificador) mas partem de fontes de dado diferentes — um padrão mais sutil do que repetição literal, e mais perigoso, porque só quebra quando as fontes divergem de fato. Foi assim que ela encontrou, nesse mesmo workflow, exatamente a divergência source_id vs. phone do incidente.
Não. Ela aponta onde centralizar (tipicamente um node Set logo após a entrada do fluxo) e lista os grupos de repetição e divergência — quem decide a fonte de verdade final e reescreve os nodes é quem conhece o fluxo.

Comentários

  • Nenhum comentário ainda.