From 875992bf03813fe9a5d9aee9b2326dda69312623 Mon Sep 17 00:00:00 2001 From: cocvn157 <120394358+cocvn157@users.noreply.github.com> Date: Thu, 5 Nov 2026 11:33:37 +0700 Subject: [PATCH] fix(core): evaluate nested event filters when parent payload is missing or null (#5017) --- .changeset/nested-exists-false-event-filter.md | 5 +++++ packages/core/src/eventFilterMatches.ts | 6 +----- packages/core/test/eventFilterMatches.test.ts | 12 ++++++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 .changeset/nested-exists-false-event-filter.md diff --git a/.changeset/nested-exists-false-event-filter.md b/.changeset/nested-exists-false-event-filter.md new file mode 100644 index 00000000000..ef22f51496d --- /dev/null +++ b/.changeset/nested-exists-false-event-filter.md @@ -0,0 +1,5 @@ +--- +"@trigger.dev/core": patch +--- + +Fix `eventFilterMatches` returning `false` for nested `$exists: false` filters when the parent key is missing or `null` diff --git a/packages/core/src/eventFilterMatches.ts b/packages/core/src/eventFilterMatches.ts index 86a78aef750..9c187c801ad 100644 --- a/packages/core/src/eventFilterMatches.ts +++ b/packages/core/src/eventFilterMatches.ts @@ -6,11 +6,7 @@ import type { EventFilter } from "./schemas/eventFilter.js"; // An example would be [{ $endsWith: ".png" }, { $startsWith: "images/" } ] export function eventFilterMatches(payload: any, filter: EventFilter): boolean { if (payload === undefined || payload === null) { - if (Object.entries(filter).length === 0) { - return true; - } else { - return false; - } + payload = {}; } for (const [patternKey, patternValue] of Object.entries(filter)) { diff --git a/packages/core/test/eventFilterMatches.test.ts b/packages/core/test/eventFilterMatches.test.ts index 4df17fa235a..69f5d6460e8 100644 --- a/packages/core/test/eventFilterMatches.test.ts +++ b/packages/core/test/eventFilterMatches.test.ts @@ -209,6 +209,18 @@ describe("eventFilterMatches", () => { expect(eventFilterMatches(payload, filter)).toBe(true); }); + it("should return true for nested $exists = false when the parent key is missing or null", () => { + const filter: EventFilter = { + user: { + email: [{ $exists: false }], + }, + }; + expect(eventFilterMatches({}, filter)).toBe(true); + expect(eventFilterMatches({ user: null }, filter)).toBe(true); + expect(eventFilterMatches({ user: {} }, filter)).toBe(true); + expect(eventFilterMatches({ user: { email: "a@b.com" } }, filter)).toBe(false); + }); + it("should return true when payload does match numeric condition", () => { const payload = { name: "John",