Input.item.query aparece como undefined. Erro de escopo ou timing?

Olá, pessoal!

Estou enfrentando um problema intrigante no meu workflow do n8n. Envio dados via Webhook através de um formulário, e os parâmetros query (como user_id) aparecem corretamente na aba “Entrada” do primeiro nó.

Porém, ao tentar acessar esses dados no nó de Código chamado "Preparar Arquivo para Salvar", a variável $input.item.query retorna undefined, mesmo quando visualizo esses dados corretamente na interface.

O que já tentei

  • Verifiquei que o parâmetro query está presente no JSON de entrada do Webhook.
  • Tentei acessar os dados usando diferentes abordagens:
    • $input.item.query
    • $request.query
    • $input.item.request.query
  • Usei console.log() para inspecionar:
    • $input
    • $node
    • $workflow
    • $request
  • Limpei cache, testei envio com aba anônima e revisei os logs com atenção.

Código Atual no Nó “Preparar Arquivo para Salvar”

// No nó "Código" ("Preparar Arquivo para Salvar") - FLUXO DE DOCUMENTOS - TENTATIVA FINAL DE ACESSO

console.log("INÍCIO DO NÓ CÓDIGO (Preparar Arquivo para Salvar) - TENTATIVA FINAL DE ACESSO DIRETO");

// Logar o objeto $input INTEIRO para inspeção máxima
// Às vezes, a estrutura real pode ser $input.workflow.query ou algo similar.
console.log("OBJETO $input COMPLETO (RAIZ):", JSON.stringify($input, null, 2));

// Logar $input.item também, para comparação com o que a UI mostra como "Entrada do Nó"
console.log("$input.item COMPLETO (ESPERADO PELA UI):", JSON.stringify($input.item, null, 2));


let userId = "USER_ID_NAO_ENCONTRADO_AINDA_NESTA_TENTATIVA";
let debugMessages = [];

debugMessages.push(`DEBUG: Tentando acessar $input.item.query diretamente na condição IF.`);
debugMessages.push(`DEBUG: Valor de $input.item.query no momento da verificação: ${JSON.stringify($input.item.query)}`);
debugMessages.push(`DEBUG: Tipo de $input.item.query no momento da verificação: ${typeof $input.item.query}`);

// Tenta acessar diretamente, sem atribuir a uma variável intermediária primeiro
if ($input.item && $input.item.query && typeof $input.item.query === 'object' && $input.item.query.user_id && typeof $input.item.query.user_id === 'string' && $input.item.query.user_id.trim() !== '') {
    userId = $input.item.query.user_id.trim();
    debugMessages.push(`SUCESSO! User ID obtido diretamente de $input.item.query.user_id: "${userId}"`);
} else {
    debugMessages.push(`FALHA ao obter user_id diretamente de $input.item.query.user_id.`);
    // Detalhar a falha da condição
    if (!$input.item) {
        debugMessages.push(`  Causa: $input.item é falsy (valor: ${$input.item})`);
    } else if (!$input.item.query) {
        debugMessages.push(`  Causa: $input.item.query é falsy (valor: ${$input.item.query})`);
    } else if (typeof $input.item.query !== 'object') {
        debugMessages.push(`  Causa: typeof $input.item.query não é 'object' (tipo: ${typeof $input.item.query})`);
    } else if (!$input.item.query.user_id) {
        debugMessages.push(`  Causa: $input.item.query.user_id é falsy (valor: ${$input.item.query.user_id})`);
    } else if (typeof $input.item.query.user_id !== 'string') {
        debugMessages.push(`  Causa: typeof $input.item.query.user_id não é 'string' (tipo: ${typeof $input.item.query.user_id})`);
    } else if ($input.item.query.user_id.trim() === '') {
        debugMessages.push(`  Causa: $input.item.query.user_id.trim() é uma string vazia (original: "${$input.item.query.user_id}")`);
    }
    userId = "USER_ID_FALHOU_NO_ACESSO_DIRETO_DETALHADO";
}


// Log de todas as mensagens de depuração coletadas
console.log("MENSAGENS DE DEPURAÇÃO (TENTATIVA FINAL DE ACESSO DIRETO):\n" + debugMessages.join("\n"));

if (userId.startsWith("USER_ID_FALHOU") || userId.startsWith("USER_ID_NAO_ENCONTRADO")) {
    console.error("ERRO FINAL (TENTATIVA FINAL DE ACESSO DIRETO): User ID não pôde ser determinado. Valor final de userId:", `"${userId}"`);
    return [{ 
        json: { 
            error: "user_id não foi encontrado ou é inválido (TENTATIVA FINAL DE ACESSO DIRETO).", 
            final_debug_userId_value: userId,
            detailed_debug_messages: debugMessages,
            input_item_query_snapshot_on_error: $input.item ? $input.item.query : "input.item is falsy"
        } 
    }];
}

console.log("CONTINUANDO O FLUXO (TENTATIVA FINAL DE ACESSO DIRETO) COM User ID:", `"${userId}"`);

// --- O restante do código para processar arquivos permanece o mesmo ---
const itemsDeSaida = [];
const fileFieldNamesFromHTML = ['documento_rg', 'documento_cpf', 'documento_certidao', 'documento_residencia', 'documento_historico', 'documento_foto'];

if ($input.item.binary && Object.keys($input.item.binary).length > 0) {
    console.log("Objeto $input.item.binary encontrado com chaves:", JSON.stringify(Object.keys($input.item.binary)));
    for (const fieldName of fileFieldNamesFromHTML) {
        if ($input.item.binary[fieldName]) {
            const fileData = $input.item.binary[fieldName];
            if (!fileData.fileName || !fileData.mimeType) {
                console.warn(`Dados do arquivo para o campo "${fieldName}" estão incompletos:`, JSON.stringify(fileData));
                continue; 
            }
            console.log(`Arquivo encontrado para o campo: ${fieldName}, Nome original: ${fileData.fileName}, Tipo MIME: ${fileData.mimeType}`);
            let docType = fieldName.replace('documento_', '');
            const originalFileNameOnDevice = fileData.fileName;
            const fileNameParts = originalFileNameOnDevice.split('.');
            const fileExtension = fileNameParts.length > 1 ? fileNameParts.pop().toLowerCase() : 'bin'; 
            const baseNewFileName = `${userId}_${docType}_${Date.now()}`;
            const newSavedOriginalFileName = `${baseNewFileName}.${fileExtension}`;
            const originalFilePathToSave = `files/formularios/documentos_originais/${newSavedOriginalFileName}`;
            const needsConversionToPdf = fileData.mimeType.startsWith('image/') && fieldName !== 'documento_foto' && fileExtension !== 'pdf';
            const finalOutputFileName = needsConversionToPdf ? `${baseNewFileName}.pdf` : newSavedOriginalFileName;
            const finalProcessedPath = `files/formularios/documentos_processados/${finalOutputFileName}`;
            itemsDeSaida.push({
                json: {
                    user_id: userId,
                    originalFileNameOnDevice: originalFileNameOnDevice,
                    savedOriginalFileName: newSavedOriginalFileName, 
                    docType: docType,
                    originalFilePathToSave: originalFilePathToSave,
                    finalProcessedPath: finalProcessedPath,
                    mimeType: fileData.mimeType,
                    needsConversionToPdf: needsConversionToPdf,
                    originalFormFieldName: fieldName 
                },
                binary: { data: fileData }
            });
        } else {
            console.log(`Arquivo para o campo "${fieldName}" NÃO encontrado em $input.item.binary.${fieldName}. (Normal se opcional)`);
        }
    }
} else {
    console.warn("$input.item.binary NÃO encontrado ou está vazio. Chaves binárias:", $input.item.binary ? JSON.stringify(Object.keys($input.item.binary)) : "undefined");
}

if (itemsDeSaida.length === 0) {
    console.log("Nenhum arquivo foi processado (ou encontrado nos campos esperados). User ID era:", `"${userId}"`);
    itemsDeSaida.push({ 
        json: { 
            user_id: userId, 
            message: "Nenhum arquivo binário processado. Verifique se os arquivos foram enviados e se os nomes dos campos no HTML correspondem. O user_id foi recebido.",
            final_debug_userId_value_at_end: userId,
            input_binary_keys_at_end: $input.item.binary ? Object.keys($input.item.binary) : "Nenhum $input.item.binary",
            input_query_params_at_end: $input.item.query
        } 
    });
}

console.log("Itens de Saída FINAIS do Nó Código (Documentos - TENTATIVA FINAL DE ACESSO DIRETO):", JSON.stringify(itemsDeSaida, null, 2));
return itemsDeSaida;

Exemplo de JSON de Entrada (Webhook)

[
  {
    "headers": {
      "host": "localhost:5678",
      "connection": "keep-alive",
      "content-length": "609955",
      "sec-ch-ua-platform": "\"Windows\"",
      "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
      "sec-ch-ua": "\"Chromium\";v=\"136\", \"Google Chrome\";v=\"136\", \"Not.A/Brand\";v=\"99\"",
      "content-type": "multipart/form-data; boundary=----WebKitFormBoundarymwbmvws3n2bd61bM",
      "sec-ch-ua-mobile": "?0",
      "accept": "*/*",
      "origin": "http://localhost",
      "sec-fetch-site": "same-site",
      "sec-fetch-mode": "cors",
      "sec-fetch-dest": "empty",
      "referer": "http://localhost/",
      "accept-encoding": "gzip, deflate, br, zstd",
      "accept-language": "pt-BR,pt;q=0.9"
    },
    "params": {},
    "query": {
      "user_id": "4a71d1e9-13f9-4837-aff9-fa64d80e9e69"
    },
    "body": {
      "user_id": "4a71d1e9-13f9-4837-aff9-fa64d80e9e69"
    },
    "webhookUrl": "http://localhost:5678/webhook/ceeja-documentos",
    "executionMode": "production"
  }
]

Dúvida Principal

Se os parâmetros query estão visíveis na Entrada do nó, por que $input.item.query está undefined na execução?
Existe alguma forma mais confiável de acessar os dados da query string enviados ao Webhook dentro de um nó de Código?

Informações do ambiente

  • **Versão do n8n: 1.36.2
  • **Hospedagem: Docker
  • Disparo: Webhook via formulário HTML
  • **Navegador utilizado: Chrome

workflow: