Consulta MongoDB retorna 0 itens na primeira execução mas funciona na segunda execução

Estou observando um comportamento muito estranho em um fluxo de trabalho do n8n usando MongoDB.
O fluxo de trabalho é:

  • Webhook recebe LeadUserID e property_id
  • Nó Set formata os dados
  • Nó MongoDB encontra o documento Campaign por property_id
  • Um segundo nó MongoDB pesquisa a coleção Campaign_Members usando:
    • Customer_ID do webhook
    • Campaign_ID (_id) do nó MongoDB anterior
      O problema é que o segundo nó MongoDB se comporta de forma inconsistente:
  • Execução automática do fluxo de trabalho → retorna 0 itens
  • Primeira execução manual no editor → retorna 0 itens
  • Segunda execução manual (sem alterar nada) → retorna com sucesso o documento correspondente
    A consulta é:
={
  "Customer_ID": "{{ $('Edit Fields').first().json.body.args.LeadUserID }}",
  "Campaign_ID": "{{ $json._id }}"
}

Os dados já existem no banco de dados, então isso não é uma condição de corrida com uma inserção recente.
O que me confunde é que nada muda entre a primeira e a segunda execução, mas a segunda execução consistentemente funciona.
Alguém já encontrou esse tipo de comportamento “primeira execução falha, segunda execução funciona” com nós MongoDB? Poderia estar relacionado a tipos de dados (como ObjectId vs string), tempo de avaliação de expressão, estado de execução ou outro tipo de peculiaridade específica do n8n?

Informações sobre sua configuração do n8n

  • Versão n8n: versão mais recente
  • Banco de dados (padrão: MongoDB):
  • Configuração n8n EXECUTIONS_PROCESS (padrão: own, main):
  • Executando n8n via: n8n cloud
  • Sistema operacional:

Oi @alee_Ostovar

Você precisa garantir que o Campaign_ID seja passado como um ObjectId.

A forma mais confiável de lidar com ObjectId no n8n é criar o objeto de consulta em um nó Code. Isso evita que o n8n converta acidentalmente seus IDs em strings.

  1. Adicione um nó Code antes do seu segundo nó MongoDB.
  2. Use este código:
const leadUserId = $('Edit Fields').first().json.body.args.LeadUserID;
const campaignId = $json._id;

return {
  query: {
    Customer_ID: leadUserId,
    Campaign_ID: { "$oid": campaignId } // Isso diz ao MongoDB para tratá-lo como um ObjectId
  }
};
  1. No seu nó MongoDB, em vez de escrever o JSON manualmente, faça referência à saída do nó Code: {{ $json.query }}

@alee_Ostovar
Tive um problema muito parecido com Postgres. Pelo que consegui entender, tinha a ver com dados fixados no gatilho, particularmente se o gatilho é um webhook ou um gatilho “Quando executado por outro fluxo de trabalho”. Embora não devesse acontecer, os dados fixados do gatilho estavam sendo transmitidos para as etapas subsequentes durante as execuções em produção e às vezes esses dados estão errados / apenas um valor nulo dos testes manuais. E então quando você abre manualmente a execução que falhou - os dados fixados do gatilho são sobrescritos e funciona como mágica.

Consegui resolver isso certificando-me de que sempre Desfico os dados do gatilho antes de meu fluxo de trabalho entrar em produção. Não aconteceu mais desde então, e costumava ocorrer talvez 50% das vezes anteriormente. Espero que isso ajude.

Obrigado pela sugestão. No meu caso, o Campaign_ID não é armazenado como um ObjectId do MongoDB. Ele é armazenado como uma string na coleção Campaign_Members (é apenas um valor de referência, não um campo ObjectId propriamente dito).

Por causa disso, envolvê-lo como { "$oid": campaignId } faria a consulta procurar por um ObjectId, que não corresponderia ao valor string armazenado.

É por isso que

Isso ocorre devido a uma incompatibilidade de tipo de dado

Obrigado, na verdade já tentei isso. Me certifiquei de que o gatilho Webhook não estava fixado, mas infelizmente o comportamento não mudou.

Uma solução alternativa que encontrei é substituir o nó Edit Fields (Set) por um nó Code que cria a mesma saída. Com o nó Code, o fluxo de trabalho funciona corretamente todas as vezes.

Também notei outro problema que parece estar relacionado ao nó Edit Fields: ao passar documentos MongoDB através dele, o _id do MongoDB às vezes é convertido em um Buffer em vez de permanecer em sua forma original. Isso parece ser um problema separado com o próprio nó Set/Edit Fields.

No momento, usar um nó Code contorna ambos os problemas, mas parece mais estar evitando o bug do que consertá-lo. Estou tentando entender por que o nó nativo Set/Edit Fields se comporta dessa maneira.

Não acho que seja uma incompatibilidade de tipo de dados, já que ambas as variables são armazenadas como strings, e a consulta também está usando valores de string. Se fosse uma incompatibilidade de tipo, eu esperaria que falhasse consistentemente em vez de apenas na primeira execução.

Consegui resolver o problema substituindo o nó Edit Fields (Set) por um nó Code. Isso funciona, mas estou tentando entender por que o nó Set nativo apresenta esse comportamento em primeiro lugar.

No MongoDB, o campo _id não é uma string; é um tipo BSON especial chamado ObjectId.

Em sua consulta:

{
  "Customer_ID": "{{ $('Edit Fields').first().json.body.args.LeadUserID }}",
  "Campaign_ID": "{{ $json._id }}"
}

Ao envolver {{ $json._id }} em aspas duplas, você está dizendo explicitamente ao n8n para tratar o Campaign_ID como uma string. Quando o MongoDB recebe uma string para um campo armazenado como ObjectId, ele retorna zero resultados porque uma string não é igual a um ObjectId, mesmo que os caracteres sejam idênticos.

Durante a primeira execução manual, o node pode não resolver a expressão exatamente como esperado ou falhar na consulta do banco de dados. No entanto, durante a segunda execução, o editor frequentemente usa a saída em cache do estado de execução do node anterior.

Isso se aplica ao seu caso?

Esta é exatamente a parte confusa, e na verdade é o segundo problema que estou enfrentando.

O nó Edit Fields às vezes passa _id como [object Object], então suspeitei que fosse um problema de tipo de dados. Para verificar, registrei o valor usando um nó Code imediatamente após um nó MongoDB (antes de um edit fields). Aqui está o resultado:

[
  {
    "value": "6a579e9014256aa1f68ca592",
    "typeof": "string",
    "constructor": "String",
    "isObject": false,
    "proto": "Object"
  }
]

Na superfície, parece ser uma string primitiva. No entanto, dado o comportamento que estou observando, suspeito que ainda possa haver um wrapper BSON subjacente ou algum tipo/proxy interno envolvido que não esteja refletido na saída do nó Code. Isso explicaria por que o nó MongoDB posteriormente trata o valor como um objeto em vez de uma string.

Para forçar que seja uma string primitiva sempre (automática ou manualmente), você deve envolver sua expressão em um construtor de string JavaScript.

Mude sua consulta de:

{
  "Customer_ID": "{{ $('Edit Fields').first().json.body.args.LeadUserID }}",
  "Campaign_ID": "{{ $json._id }}"
}

Para:

{
  "Customer_ID": "{{ String($('Edit Fields').first().json.body.args.LeadUserID) }}",
  "Campaign_ID": "{{ String($json._id) }}"
}

Ao envolver a expressão em String(), você força o engine de expressão do n8n a executar uma conversão de tipo JavaScript antes do valor ser passado para o nó MongoDB. Isso remove qualquer wrapper BSON, proxies ou metadados de objeto, garantindo que o MongoDB receba uma string literal todas as vezes.