fix(feature-flags): persist false value in flag dependency conditions#60303
Conversation
Generated-By: PostHog Code Task-Id: 8dda03e1-e728-4ca8-9e20-45234a9735fa
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
🎭 Playwright didn't run on this PR — your changes touch code that could affect E2E behavior, but Playwright is opt-in via label now to keep CI cost down. Add the Most PRs don't need this. Real regressions still get caught on master and fix-forward. |
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
frontend/src/lib/components/PropertyFilters/propertyFilterLogic.test.ts:122-137
The two new tests cover the same scenario (a previously-truthy-short-circuited value that is now allowed through). The project's convention is to prefer parameterised tests, so these could be collapsed into a single `it.each` block. The `value: 0` case also skips the value-preservation assertion that the `value: false` case includes — adding it makes both cases complete.
```suggestion
it.each([
[
'boolean false (flag dependency)',
{
key: '911',
type: PropertyFilterType.Flag,
operator: PropertyOperator.FlagEvaluatesTo,
value: false,
} as AnyPropertyFilter,
false,
],
['number 0', eventFilter('$browser', 0 as any, PropertyOperator.Exact), 0],
])('calls onChange when the value is %s', async (_, filter, expectedValue) => {
const cb = await setFilterAndCheck(filter, false)
expect(cb).toHaveBeenCalledTimes(1)
expect(cb.mock.calls[0][0][0]).toMatchObject({ value: expectedValue })
})
```
Reviews (1): Last reviewed commit: "fix(feature-flags): persist false value ..." | Re-trigger Greptile |
|
Size Change: 0 B Total Size: 80.2 MB ℹ️ View Unchanged
|
There was a problem hiding this comment.
Pull request overview
Fixes a frontend regression in propertyFilterLogic.setFilter where falsy-but-valid filter values (notably false for flag dependencies and 0 for numeric filters) were treated as “no value”, preventing actions.update() from firing and thus skipping the parent onChange/API payload update.
Changes:
- Replaced a truthiness-based
hasValuecheck with explicit null/undefined/empty-string/empty-array checks sofalseand0propagate correctly. - Added regression tests ensuring
onChangefires forvalue: false(flag dependency) andvalue: 0(numeric).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| frontend/src/lib/components/PropertyFilters/propertyFilterLogic.ts | Updates hasValue gating so valid falsy values trigger update()/onChange. |
| frontend/src/lib/components/PropertyFilters/propertyFilterLogic.test.ts | Adds regression tests for boolean false and numeric 0 values. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Generated-By: PostHog Code Task-Id: 8dda03e1-e728-4ca8-9e20-45234a9735fa
…rValue Generated-By: PostHog Code Task-Id: 8dda03e1-e728-4ca8-9e20-45234a9735fa
…tener Generated-By: PostHog Code Task-Id: 8dda03e1-e728-4ca8-9e20-45234a9735fa

Problem
When editing a feature flag with a condition that depends on another flag, changing the dependency value from
truetofalsedid not persist. The API was never called withfalse— the UI silently kept the previous value.Changes
Fixed the truthy check in
propertyFilterLogic.setFilterthat gatedactions.update().property.value && ...short-circuited onfalse(and0), so the listener never propagated valid boolean/numeric values to the parentonChange. Replaced it with explicit null/undefined/empty-string/empty-array checks.How did you test this code?
I am an agent (PostHog Code). Verified via automated tests only:
propertyFilterLogic.test.tscovering a flag dependency filter withvalue: falseand a numeric filter withvalue: 0.propertyFilterLogic.test.tssuite — 22/22 passing.👉 Stay up-to-date with PostHog coding conventions for a smoother review.
Publish to changelog?
no
🤖 Agent context
Authored by PostHog Code (Claude Opus 4.7).
Investigation path:
value: trueeven after selectingfalse— so the regression was frontend-side, not the serializer.flag/flag_evaluates_tofilter flow:PropertyValue→OperatorValueSelect→propertyFilterLogic.setFilter.isValidPropertyFilter(utils.ts) as a possible suspect but ruled it out —keyandtypeare truthy strings, so the filter survives the cleanup pass. The change-propagation gate insetFilterwas the only place that silently droppedfalse.undefined/null/""/[]so unrelated flows (e.g. typing-in-progress) keep behaving the same.Created with PostHog Code