From 2623052736e317db3a8edc531b694ed32ef88e1f Mon Sep 17 00:00:00 2001 From: "Jeremy D. Miller" Date: Fri, 10 Apr 2026 06:13:52 -0500 Subject: [PATCH] Remove OTEL Activity from circuit breaker pause path to fix trace ID leak (#2494) After a circuit breaker trip/resume cycle, the Activity started on the background batching thread leaked its trace context via AsyncLocal into subsequent message processing, causing all new messages to inherit the stale trace ID. Remove the Activity creation from both the circuit breaker trip handler and the listener PauseAsync method to prevent this contamination. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/Wolverine/ErrorHandling/CircuitBreaker.cs | 2 -- src/Wolverine/Transports/ListeningAgent.cs | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/Wolverine/ErrorHandling/CircuitBreaker.cs b/src/Wolverine/ErrorHandling/CircuitBreaker.cs index e5efe03b0..4cb38fe60 100644 --- a/src/Wolverine/ErrorHandling/CircuitBreaker.cs +++ b/src/Wolverine/ErrorHandling/CircuitBreaker.cs @@ -177,8 +177,6 @@ public async ValueTask UpdateTotalsAsync(DateTimeOffset time, int failures, int if (failures > 0 && ShouldStopProcessing()) { - using var activity = WolverineTracing.ActivitySource.StartActivity(WolverineTracing.CircuitBreakerTripped); - activity?.SetTag(WolverineTracing.EndpointAddress, _circuit.Endpoint.Uri); await _circuit.PauseAsync(Options.PauseTime); if (_observer != null) diff --git a/src/Wolverine/Transports/ListeningAgent.cs b/src/Wolverine/Transports/ListeningAgent.cs index 60699ee52..aa47a2fc1 100644 --- a/src/Wolverine/Transports/ListeningAgent.cs +++ b/src/Wolverine/Transports/ListeningAgent.cs @@ -350,8 +350,6 @@ public async ValueTask PauseAsync(TimeSpan pauseTime) { try { - using var activity = WolverineTracing.ActivitySource.StartActivity(WolverineTracing.PausingListener); - activity?.SetTag(WolverineTracing.EndpointAddress, Uri); // Do NOT pre-latch the receiver here. PauseAsync may be called from within the // handler pipeline (e.g. via RateLimitContinuation → PauseListenerContinuation). // Pre-latching causes DrainAsync to wait for the ActionBlock to drain, which