## Summary Fixes #18744 — The workflow FIND_RECORDS action silently drops filter conditions when a variable resolves to null/empty, causing the query to return **all records** instead of erroring. **Root cause (three compounding layers):** 1. **`variable-resolver.ts`** — `resolveString` returns `undefined` when a variable lookup fails (e.g., `{{steps.trigger.output.userId}}` where `userId` doesn't exist in context). The return type says `string` but `evalFromContext` actually returns `undefined` at runtime. 2. **`checkIfShouldSkipFiltering.ts`** — Treats `undefined`/`null`/`""` values as "skip this filter." This is correct for the **UI filter builder** (user hasn't finished typing), but wrong for **workflow execution** (variable resolution failed = misconfigured workflow). 3. **`find-records.workflow-action.ts`** — When all filters are silently skipped, `computeRecordGqlOperationFilter` returns `{}` (match everything). The query runs with no filter, returning all records — silently succeeding with wrong results. ## Fix Added validation in `find-records.workflow-action.ts` **after** `resolveInput` but **before** `computeRecordGqlOperationFilter`. For each filter with a value-requiring operand (i.e., not IS_EMPTY, IS_NOT_EMPTY, IS_IN_PAST, IS_IN_FUTURE, IS_TODAY), if the resolved value is `undefined`, `null`, or `""`, throw `INVALID_STEP_INPUT` with a descriptive error message. **Why this approach:** - Scoped to the workflow executor — does **not** break the UI filter builder's intentional skip-on-empty behavior - Does not change shared utilities (`checkIfShouldSkipFiltering`, `resolveInput`) used across the app - Fails fast with a clear error instead of silently returning wrong data - 1 file changed, 23 lines added ## Test plan - [x] Backend typecheck passes - [x] oxlint passes (0 warnings, 0 errors) - [x] Prettier passes - [ ] Manual: Create a workflow with FIND_RECORDS using a variable that doesn't exist → should error with "Filter condition has an empty value after variable resolution" instead of returning all records - [ ] Manual: Create a workflow with FIND_RECORDS using IS_EMPTY operand (no value needed) → should still work correctly --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Charles Bochet <charles@twenty.com>
The #1 Open-Source CRM
🌐 Website · 📚 Documentation · Roadmap ·
Discord ·
Figma
Installation
See: 🚀 Self-hosting 🖥️ Local Setup
Why Twenty
We built Twenty for three reasons:
CRMs are too expensive, and users are trapped. Companies use locked-in customer data to hike prices. It shouldn't be that way.
A fresh start is required to build a better experience. We can learn from past mistakes and craft a cohesive experience inspired by new UX patterns from tools like Notion, Airtable or Linear.
We believe in open-source and community. Hundreds of developers are already building Twenty together. Once we have plugin capabilities, a whole ecosystem will grow around it.
What You Can Do With Twenty
Please feel free to flag any specific needs you have by creating an issue.
Below are a few features we have implemented to date:
- Personalize layouts with filters, sort, group by, kanban and table views
- Customize your objects and fields
- Create and manage permissions with custom roles
- Automate workflow with triggers and actions
- Emails, calendar events, files, and more
Personalize layouts with filters, sort, group by, kanban and table views
Customize your objects and fields
Create and manage permissions with custom roles
Automate workflow with triggers and actions
Emails, calendar events, files, and more
Stack
- TypeScript
- Nx
- NestJS, with BullMQ, PostgreSQL, Redis
- React, with Jotai, Linaria and Lingui
Thanks
Thanks to these amazing services that we use and recommend for UI testing (Chromatic), code review (Greptile), catching bugs (Sentry) and translating (Crowdin).
Join the Community
- Star the repo
- Subscribe to releases (watch -> custom -> releases)
- Follow us on Twitter or LinkedIn
- Join our Discord
- Improve translations on Crowdin
- Contributions are, of course, most welcome!




