Skip to content

Fix timestamp type mismatch between proto (uint64) and envelope (int64) #12

@lanycrost

Description

@lanycrost

Problem statement

Proto messages use uint64 timestamp_ms (unsigned) while the Go envelope struct uses int64 TimestampMs (signed). The conversion between them has edge cases:

  • int64 → uint64: negative TimestampMs values produce massive positive timestamps
  • uint64 → int64: values > math.MaxInt64 produce negative values

Current conversion code in envelope.go:

// ToBinaryFrame (line 115-118)
if env != nil && env.TimestampMs > 0 {
    frame.TimestampMs = uint64(env.TimestampMs)  // int64 → uint64
}

// FromBinaryFrame (line 133-136)
if env.TimestampMs == 0 && frame.GetTimestampMs() > 0 {
    env.TimestampMs = int64(frame.GetTimestampMs())  // uint64 → int64
}

While millisecond timestamps won't practically overflow in our lifetimes, the type mismatch signals unclear design intent and makes the code fragile.

Proposed change

Standardize on uint64 in the envelope since timestamps can never be negative:

type Envelope struct {
    TimestampMs uint64 `json:"timestampMs,omitempty"`
    // ...
}

This eliminates both conversion paths and aligns with the proto definition.

Alternative: Use int64 everywhere (proto + envelope) since JSON doesn't have unsigned integers and some languages (Java, JavaScript) lack native uint64. If choosing this path, change the proto field to int64 timestamp_ms — varint encoding is compatible for positive values.

Affected area

  • Proto definitions (if changing proto type)
  • Envelope helpers

Compatibility / migration

  • Changing envelope Go struct type: breaking for any downstream code that assigns int64 to TimestampMs
  • Changing proto type: wire-compatible for positive values (varint encoding is the same), but type-incompatible in generated code
  • Either direction requires a coordinated change across core, SDK, and hub

Additional context

Identified during architectural review. The > 0 guard in ToBinaryFrame masks the negative-value issue but doesn't solve it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/envelopeJSON envelope helpers and MIME-contract behavior.area/protoProto definitions, message design, or wire compatibility work.good first issueSmall, well-scoped tasks for new contributors.help wantedLooking for community contributions.kind/bugUnexpected behaviour or regression that needs fixing.priority/mediumNormal priority item.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions