Skip to content

fix: sanitize None values from event properties before queueing - #926

Closed
hariom123-dev wants to merge 1 commit into
PostHog:mainfrom
hariom123-dev:fix/sanitize-event-properties
Closed

fix: sanitize None values from event properties before queueing#926
hariom123-dev wants to merge 1 commit into
PostHog:mainfrom
hariom123-dev:fix/sanitize-event-properties

Conversation

@hariom123-dev

Copy link
Copy Markdown

TL;DR

Adds defensive sanitization to the message queueing flow to strip None values from event properties before they are batched and sent over the network.

🔍 Context & Motivation

When developers pass dynamic property dictionaries into posthog.capture() (e.g., pulling data from an external API or scraper), keys with None values can easily slip in.

Currently, these null values are queued, serialized into JSON, and sent to the PostHog API. This causes two minor issues:

  1. Network & Storage Inefficiency: Sending { "optional_field": null } across the wire consumes unnecessary bandwidth and inflates the size of the event payload.
  2. Dashboard Clutter: Null properties can clutter the PostHog dashboard UI, showing fields that contain no actionable analytics data.

🛠️ Changes Implemented

Added a lightweight dictionary comprehension in posthog/client.py during the internal message preparation phase. It checks if msg.get("properties") is a dictionary, and if so, it filters out any keys where the value is explicitly None right before the msg is cleaned and appended to the batch.

Note: Empty strings, 0, and False are preserved, as they are often valid analytics values.

✅ Verification

  • Unit Test: Added test_capture_sanitizes_none_properties in posthog/test/test_client.py. It simulates a client.capture call with both valid and None properties, mocking the network request to assert the batched payload only retains the valid keys.
  • Local Tests: Verified using local test suite without breaking existing queueing behavior.

📉 Impact

  • Safe: 100% backward-compatible. Valid properties remain untouched.
  • Fast: Standard O(n) Python dictionary comprehension adds negligible overhead to the queueing process.

@hariom123-dev
hariom123-dev requested a review from a team as a code owner September 7, 2026 16:18
@marandaneto

marandaneto commented Sep 8, 2026

Copy link
Copy Markdown
Member

none serializes to null values and its a valid JSON so it's working as intended
you can strip those values in the before send callback if you dont need them

edit: its ok to pass none but we'll strip those during serialization so not really worth passing them
i will follow up with a separate pr, sry and thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants