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

Ouverte Adaptée aux débutants
#5,017 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

  • #5023 par @GauravPatil2515 — fermée sans fusion
  • #5099 par @cocvn157 — fermée sans fusion

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
78/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
node.js, typescript
Domaine
backend, testing

Piste de recherche

Commence par packages/core/src/eventFilterMatches.ts et les cas existants dans packages/core/test/eventFilterMatches.test.ts. Reproduis les cas imbriqués de $exists: false de l’issue, y compris ceux où les clés parentes sont absentes ou nulles, puis vérifie que les cas de premier niveau passent toujours. Le travail est terminé lorsque les quatre résultats signalés renvoient true et que les tests existants passent.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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.

Langage dominant
TypeScript
Étoiles
16.5k
Forks
1.5k
Merge moyen
1 j 15 h
PR mergées (30 j)
17

Préparer son environnement

Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de triggerdotdev/trigger.dev

Toutes les issues de triggerdotdev/trigger.dev

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.