Skip to content

Nullable in serialization corrupts JSON #139

@NickKhalow

Description

@NickKhalow

Segment.Serialization.JsonObject – Critical Serialization Bug

Describe the Bug

There is a critical JSON serialization defect in Segment.Serialization.JsonObject.
The serializer produces invalid JSON when serializing Nullable<T> fields, resulting in malformed fragments such as:

"is_empty_scene": ,

instead of:

"is_empty_scene": null

This breaks JSON format and causes Segment’s ingestion pipeline to silently drop events.

Our custom Rust implementation revealed the issue by producing correct JSON, making the discrepancy visible.


To Reproduce

  1. Download the reproduction project:
    https://github.com/NickKhalow/JsonBugReproSegment
  2. Run the test suite.
  3. Observe malformed JSON output produced by JsonObject when handling nullable fields.

Example of the broken output:

{"scene_hash": null,"old_parcel": "(NaN, NaN)","is_empty_scene": ,"new_parcel": "(1, -1)"}

Notice "is_empty_scene": , - the value is missing entirely.


Expected Behavior

JsonObject should correctly serialize Nullable<T> values:

  • Nullable
  • Nullable
  • Nullable

Expected valid JSON:

"is_empty_scene": true

or:

"is_empty_scene": null

but never:

"is_empty_scene": ,

This violates the JSON specification and corrupts the payload.


Platform

  • Library: Segment.Serialization.JsonObject
  • Version: In production where the critical bug was found - 2.4.2 , repro project with the latest version at the moment - 2.5.3
  • Platform: .NET and Unity
  • Integrations: None (reproduces in isolation)

Additional Context

The bug is due to incorrect handling of Nullable<T> inside JsonObjectConverter.
When a nullable value is null, the serializer emits nothing, leaving a dangling comma and creating invalid JSON.

The silently ignore malformed payloads, this issue resulted in consistent unnoticed loss of analytics events.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions