diff --git a/posthog/client.py b/posthog/client.py index 59ccb9dc..eacaac28 100644 --- a/posthog/client.py +++ b/posthog/client.py @@ -2329,6 +2329,9 @@ def _enqueue(self, msg, disable_geoip, lane=None, property_allowlist=None): k: v for k, v in msg["properties"].items() if k in property_allowlist } + if isinstance(msg.get("properties"), dict): + msg["properties"] = {k: v for k, v in msg["properties"].items() if v is not None} + msg["distinct_id"] = stringify_id(msg.get("distinct_id", None)) msg = clean(msg) diff --git a/posthog/test/test_client.py b/posthog/test/test_client.py index 087a79ca..65af41b2 100644 --- a/posthog/test/test_client.py +++ b/posthog/test/test_client.py @@ -402,6 +402,23 @@ def test_basic_capture(self): assert msg["properties"]["$os"] == mock.ANY assert msg["properties"]["$os_version"] == mock.ANY + def test_capture_sanitizes_none_properties(self): + with mock.patch("posthog.client.batch_post") as mock_post: + client = Client(FAKE_TEST_API_KEY, on_error=self.set_fail, sync_mode=True) + client.capture( + "python test event", + distinct_id="distinct_id", + properties={"valid": 123, "invalid": None} + ) + self.assertFalse(self.failed) + + mock_post.assert_called_once() + msg = mock_post.call_args[1]["batch"][0] + + self.assertIn("valid", msg["properties"]) + self.assertEqual(msg["properties"]["valid"], 123) + self.assertNotIn("invalid", msg["properties"]) + def test_capture_omits_is_server_when_disabled(self): with mock.patch("posthog.client.batch_post") as mock_post: client = Client(