diff --git a/posthog/client.py b/posthog/client.py index 8f258a1c..d38253b7 100644 --- a/posthog/client.py +++ b/posthog/client.py @@ -245,7 +245,7 @@ def capture( except Exception as e: self.log.exception(f"[FEATURE FLAGS] Unable to get feature variants: {e}") - elif self.feature_flags: + elif self.feature_flags and event != "$feature_flag_called": # Local evaluation is enabled, flags are loaded, so try and get all flags we can without going to the server feature_variants = self.get_all_flags( distinct_id, groups=(groups or {}), disable_geoip=disable_geoip, only_evaluate_locally=True diff --git a/posthog/test/test_feature_flags.py b/posthog/test/test_feature_flags.py index b46d4cfd..62de7300 100644 --- a/posthog/test/test_feature_flags.py +++ b/posthog/test/test_feature_flags.py @@ -2339,6 +2339,55 @@ def test_capture_is_called(self, patch_decide, patch_capture): disable_geoip=None, ) + @mock.patch("posthog.client.decide") + def test_capture_is_called_but_does_not_add_all_flags(self, patch_decide): + patch_decide.return_value = {"featureFlags": {"decide-flag": "decide-value"}} + client = Client(FAKE_TEST_API_KEY, personal_api_key=FAKE_TEST_API_KEY) + client.feature_flags = [ + { + "id": 1, + "name": "Beta Feature", + "key": "complex-flag", + "active": True, + "filters": { + "groups": [ + { + "properties": [{"key": "region", "value": "USA"}], + "rollout_percentage": 100, + }, + ], + }, + }, + { + "id": 2, + "name": "Gamma Feature", + "key": "simple-flag", + "active": True, + "filters": { + "groups": [ + { + "properties": [], + "rollout_percentage": 100, + }, + ], + }, + }, + ] + + self.assertTrue( + client.get_feature_flag("complex-flag", "some-distinct-id", person_properties={"region": "USA"}) + ) + + # Grab the capture message that was just added to the queue + msg = client.queue.get(block=False) + assert msg["event"] == "$feature_flag_called" + assert msg["properties"]["$feature_flag"] == "complex-flag" + assert msg["properties"]["$feature_flag_response"] is True + assert msg["properties"]["locally_evaluated"] is True + assert msg["properties"]["$feature/complex-flag"] is True + assert "$feature/simple-flag" not in msg["properties"] + assert "$active_feature_flags" not in msg["properties"] + @mock.patch.object(Client, "capture") @mock.patch("posthog.client.decide") def test_capture_is_called_in_get_feature_flag_payload(self, patch_decide, patch_capture):