Skip to content

fix: omit protobuf data for events without payload - #1286

Open
immanuwell wants to merge 1 commit into
cloudevents:mainfrom
immanuwell:1193-fix-protobuf-empty-data-json
Open

fix: omit protobuf data for events without payload#1286
immanuwell wants to merge 1 commit into
cloudevents:mainfrom
immanuwell:1193-fix-protobuf-empty-data-json

Conversation

@immanuwell

Copy link
Copy Markdown

Fixes #1193

protobuf marshal always sets data, even when the event has no payload.
after a protobuf round trip that becomes DataEncoded=[]byte{}, then JSON marshal emits busted JSON:

{"specversion":"1.0","id":"id","source":"source","type":"type","datacontenttype":"application/json","data":}

Repro on main:

ev := ce.NewEvent(ce.VersionV1)
ev.SetID("id")
ev.SetSource("source")
ev.SetType("type")
ev.SetDataContentType(ce.ApplicationJSON)

b, _ := format.Protobuf.Marshal(&ev)
var out ce.Event
_ = format.Protobuf.Unmarshal(b, &out)
_, _ = out.MarshalJSON()

This patch skips protobuf data when e.Data() == nil, so no payload stays no payload. small fix, but pretty real.

Tests:

  • add a regression test for protobuf -> event -> json round trip with no data
  • go test ./... in binding/format/protobuf/v2
  • go test ./... in v2

Signed-off-by: immanuwell <pchpr.00@list.ru>
@immanuwell
immanuwell requested a review from a team as a code owner May 24, 2026 14:29
@duglin

duglin commented May 24, 2026

Copy link
Copy Markdown
Contributor

@immanuwell thanks. Fix seems ok but I have a question, why would json Marshal() ever return bad json like that? It doesn't seem possible to me even if the data were nil

@duglin

duglin commented May 24, 2026

Copy link
Copy Markdown
Contributor

Since we can't control all of the messages we might receive it feels like we might want to also add protection against receiving these nil port but messages, no?

@kunalworldwide kunalworldwide left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good fix. Without this, ToProto always sets Data to a BinaryData wrapper even when the event has no payload. That empty BinaryData{BinaryData: nil} gets serialized as a zero-length bytes field in protobuf, which on the Unmarshal side creates an empty []byte{} instead of nil — and when that's subsequently marshalled to JSON, you get "data_base64":"" instead of no data field at all, producing invalid JSON for events like heartbeats that intentionally have no payload.

The guard on DataContentType == ContentTypeProtobuf is also correct — no point trying to wrap nil data into an Any message.

Test is thorough: roundtrips through protobuf marshal/unmarshal, verifies DataEncoded is nil, then confirms the JSON output is clean and re-parseable.

LGTM.

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.

JSON marshalling produces invalid JSON when data is a zero length slice

3 participants