Bug: eventFilterMatches returns false for nested $exists: false when the parent key is missing or null

Aberta Para iniciantes
#5,017 1 comentário 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

  • #5023 de @GauravPatil2515 — fechado sem integrar
  • #5099 de @cocvn157 — fechado sem integrar

Avaliação

Dificuldade
2/5
Tempo estimado
1-3 horas
Facilidade para iniciantes
78/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
node.js, typescript
Domínio
backend, testing

Direção de pesquisa

Comece por packages/core/src/eventFilterMatches.ts e pelos casos existentes em packages/core/test/eventFilterMatches.test.ts. Reproduza os casos aninhados de $exists: false da issue, incluindo os casos em que as chaves pai estão ausentes ou são null, e depois verifique se os casos de nível superior continuam passando. O trabalho estará concluído quando os quatro resultados relatados retornarem true e os testes existentes passarem.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

Summary

eventFilterMatches returns false for a nested $exists: false filter when the parent key is missing or null in the payload. The function returns false for any non-empty filter as soon as it meets an undefined/null payload, before it evaluates $exists. This is user-facing through retry.fetch's bodyFilter, which calls eventFilterMatches on the response body.

Reproduction

  1. Setup: packages/core on main.
  2. Command: npx tsx repro.ts from packages/core with:
import { eventFilterMatches } from "./src/eventFilterMatches.js";
const f = { user: { email: [{ $exists: false }] } };
console.log(eventFilterMatches({}, f));             // false
console.log(eventFilterMatches({ user: null }, f)); // false
console.log(eventFilterMatches({ user: {} }, f));   // true
console.log(eventFilterMatches({}, { email: [{ $exists: false }] })); // true
  1. Trigger: a nested filter whose leaf is $exists: false, used with a payload where an ancestor key is absent or null.

Actual behavior

{} {"user":{"email":[{"$exists":false}]}} => false
{"user":null} {"user":{"email":[{"$exists":false}]}} => false
{"user":{}} {"user":{"email":[{"$exists":false}]}} => true
{} {"email":[{"$exists":false}]} => true

Expected behavior

All four should return true. If user is missing, then user.email doesn't exist either, which is exactly what $exists: false asserts. Top-level $exists: false already behaves that way (case 4, and the existing test "should return true when payload does NOT have a key that $exists = false"). Nesting the same condition one level deeper shouldn't flip the result.

Environment

  • Version/commit: main @ 93465d8549a735074d1ce7696bae3faebe577e8d
  • OS: Ubuntu (Linux), Node v24.21.0
  • Relevant configuration: none; pure function. Reachable from retry.fetch(url, { retry: { byStatus: { "...": { strategy: "backoff", bodyFilter } } } })

Evidence

Additional context

Confirmed: the four results above, from running the source on main.

Inference: for retry.fetch, a bodyFilter such as { error: { retryAfter: [{ $exists: false }] } } won't match a body that has no error object at all. That strategy is then skipped. I haven't exercised this through retry.fetch end to end.

Possible fix: when the payload is undefined/null, evaluate the filter against an empty object (or recurse with {}) instead of returning false, so that $exists: false and $isNull-style leaves still get evaluated.

Found with an anti-slop oxlint scan (no-runtime-typeof), then checked by hand.

Linguagem predominante
TypeScript
Estrelas
16.5k
Forks
1.5k
Merge médio
1d 15h
PRs com merge (30d)
17

Preparar o ambiente

Este projeto não oferece contêiner de desenvolvimento, Dockerfile nem guia de contribuição, então a configuração fica por sua conta: comece pelo README e veja nosso guia da primeira contribuição para os passos gerais.

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de triggerdotdev/trigger.dev

Todas as issues de triggerdotdev/trigger.dev

Issues semelhantes

Mais issues de TypeScript

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.