Skip to content

Commit 51c16dc

Browse files
romtsnclaude
andcommitted
fix(core): Inject replayId into trace context for buffer mode errors
In buffer mode, the scope's replayId is empty until captureReplay() is called. But the event's trace context is built from the transaction's frozen baggage, which was frozen before captureReplay() set the replayId. This means error events that trigger a buffer replay flush are never linked to the replay. After captureReplay() runs, check if the scope has a replayId that the trace context is missing and inject it via a new withReplayId copy method on TraceContext. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a979f23 commit 51c16dc

3 files changed

Lines changed: 29 additions & 1 deletion

File tree

sentry/api/sentry.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4567,6 +4567,7 @@ public final class io/sentry/TraceContext : io/sentry/JsonSerializable, io/sentr
45674567
public fun getUserId ()Ljava/lang/String;
45684568
public fun serialize (Lio/sentry/ObjectWriter;Lio/sentry/ILogger;)V
45694569
public fun setUnknown (Ljava/util/Map;)V
4570+
public fun withReplayId (Lio/sentry/protocol/SentryId;)Lio/sentry/TraceContext;
45704571
}
45714572

45724573
public final class io/sentry/TraceContext$Deserializer : io/sentry/JsonDeserializer {

sentry/src/main/java/io/sentry/SentryClient.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,16 @@ private boolean shouldApplyScopeData(final @NotNull CheckIn event, final @NotNul
254254
}
255255

256256
try {
257-
final @Nullable TraceContext traceContext = getTraceContext(scope, hint, event);
257+
@Nullable TraceContext traceContext = getTraceContext(scope, hint, event);
258+
if (traceContext != null && scope != null) {
259+
final @Nullable SentryId replayId = scope.getReplayId();
260+
if (replayId != null
261+
&& !replayId.equals(SentryId.EMPTY_ID)
262+
&& (traceContext.getReplayId() == null
263+
|| SentryId.EMPTY_ID.equals(traceContext.getReplayId()))) {
264+
traceContext = traceContext.withReplayId(replayId);
265+
}
266+
}
258267
final boolean shouldSendAttachments = event != null;
259268
List<Attachment> attachments = shouldSendAttachments ? getAttachments(hint) : null;
260269
final @Nullable SentryEnvelope envelope =

sentry/src/main/java/io/sentry/TraceContext.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,24 @@ public final class TraceContext implements JsonUnknown, JsonSerializable {
131131
return replayId;
132132
}
133133

134+
@ApiStatus.Internal
135+
public @NotNull TraceContext withReplayId(final @NotNull SentryId replayId) {
136+
final TraceContext copy =
137+
new TraceContext(
138+
traceId,
139+
publicKey,
140+
release,
141+
environment,
142+
userId,
143+
transaction,
144+
sampleRate,
145+
sampled,
146+
replayId,
147+
sampleRand);
148+
copy.unknown = unknown;
149+
return copy;
150+
}
151+
134152
// region json
135153

136154
@Nullable

0 commit comments

Comments
 (0)