diff --git a/src/contrib/testkits/Akka.TestKit.Xunit.Tests/Bugfix8144Spec.cs b/src/contrib/testkits/Akka.TestKit.Xunit.Tests/Bugfix8144Spec.cs
new file mode 100644
index 00000000000..06b5f2d4799
--- /dev/null
+++ b/src/contrib/testkits/Akka.TestKit.Xunit.Tests/Bugfix8144Spec.cs
@@ -0,0 +1,47 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2022 Lightbend Inc.
+// Copyright (C) 2013-2026 .NET Foundation
+//
+// -----------------------------------------------------------------------
+
+using System;
+using System.Threading.Tasks;
+using Akka.Actor;
+using Akka.TestKit.TestActors;
+using Xunit;
+
+namespace Akka.TestKit.Tests;
+
+///
+/// Verifies that implicit sender (TestActor) is preserved across async boundaries.
+/// Regression test for https://github.com/akkadotnet/akka.net/issues/8144
+///
+public class Bugfix8144Spec: Xunit.TestKit, IAsyncLifetime
+{
+ public ValueTask DisposeAsync()
+ {
+ return new ValueTask(Task.CompletedTask);
+ }
+
+ public async ValueTask InitializeAsync()
+ {
+ // Any await here can cause a thread switch, which previously
+ // lost the [ThreadStatic] InternalCurrentActorCellKeeper.Current
+ await Task.Delay(TimeSpan.FromMilliseconds(100));
+ }
+
+ [Fact]
+ public void Should_use_implicit_TestActor_sender_after_async_initialization()
+ {
+ // SimpleEchoActor echoes back to Sender - tests that implicit sender works
+ var actor = Sys.ActorOf(SimpleEchoActor.Props());
+
+ // This uses ActorRefImplicitSenderExtensions.Tell which resolves
+ // the sender via ActorCell.GetCurrentSelfOrNoSender()
+ actor.Tell("hello");
+
+ // Should receive the echo back at TestActor
+ ExpectMsg("hello");
+ }
+}
diff --git a/src/contrib/testkits/Akka.TestKit.Xunit/TestKit.cs b/src/contrib/testkits/Akka.TestKit.Xunit/TestKit.cs
index f81c18b39ca..57690b599f9 100644
--- a/src/contrib/testkits/Akka.TestKit.Xunit/TestKit.cs
+++ b/src/contrib/testkits/Akka.TestKit.Xunit/TestKit.cs
@@ -139,6 +139,47 @@ public TestKit(string config, ITestOutputHelper? output = null)
InitializeLogger(Sys);
}
+ ///
+ /// Ensures the implicit sender () is set
+ /// on the current thread. This is needed because the [ThreadStatic] value can be lost
+ /// when IAsyncLifetime.InitializeAsync contains an await that causes a thread switch.
+ /// Called automatically when accessing or .
+ ///
+ private void EnsureImplicitSender()
+ {
+ // Only set the implicit sender if Current is not already set.
+ // During actor message processing, Mailbox.Run() sets Current to the actor's cell.
+ // Overwriting it here would corrupt the actor context for the rest of that mailbox run.
+ if (this is not INoImplicitSender && InternalCurrentActorCellKeeper.Current == null)
+ InternalCurrentActorCellKeeper.Current = (ActorCell)((ActorRefWithCell)base.TestActor).Underlying;
+ }
+
+ ///
+ /// The used for testing. Accessing this property ensures the
+ /// implicit sender is set on the current thread.
+ ///
+ public new ActorSystem Sys
+ {
+ get
+ {
+ EnsureImplicitSender();
+ return base.Sys;
+ }
+ }
+
+ ///
+ /// The default test actor. Accessing this property ensures the implicit sender
+ /// is set on the current thread.
+ ///
+ public new IActorRef TestActor
+ {
+ get
+ {
+ EnsureImplicitSender();
+ return base.TestActor;
+ }
+ }
+
///
/// A configuration that has just the default log settings enabled. The default settings can be found in
/// Akka.TestKit.Internal.Reference.conf.
diff --git a/src/contrib/testkits/Akka.TestKit.Xunit2.Tests/Bugfix8144Spec.cs b/src/contrib/testkits/Akka.TestKit.Xunit2.Tests/Bugfix8144Spec.cs
new file mode 100644
index 00000000000..82ae1984b3e
--- /dev/null
+++ b/src/contrib/testkits/Akka.TestKit.Xunit2.Tests/Bugfix8144Spec.cs
@@ -0,0 +1,47 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (C) 2009-2022 Lightbend Inc.
+// Copyright (C) 2013-2026 .NET Foundation
+//
+// -----------------------------------------------------------------------
+
+using System;
+using System.Threading.Tasks;
+using Akka.Actor;
+using Akka.TestKit.TestActors;
+using Xunit;
+
+namespace Akka.TestKit.Tests;
+
+///
+/// Verifies that implicit sender (TestActor) is preserved across async boundaries.
+/// Regression test for https://github.com/akkadotnet/akka.net/issues/8144
+///
+public class Bugfix8144Spec: Xunit2.TestKit, IAsyncLifetime
+{
+ public Task DisposeAsync()
+ {
+ return Task.CompletedTask;
+ }
+
+ public async Task InitializeAsync()
+ {
+ // Any await here can cause a thread switch, which previously
+ // lost the [ThreadStatic] InternalCurrentActorCellKeeper.Current
+ await Task.Delay(TimeSpan.FromMilliseconds(100));
+ }
+
+ [Fact]
+ public void Should_use_implicit_TestActor_sender_after_async_initialization()
+ {
+ // SimpleEchoActor echoes back to Sender - tests that implicit sender works
+ var actor = Sys.ActorOf(SimpleEchoActor.Props());
+
+ // This uses ActorRefImplicitSenderExtensions.Tell which resolves
+ // the sender via ActorCell.GetCurrentSelfOrNoSender()
+ actor.Tell("hello");
+
+ // Should receive the echo back at TestActor
+ ExpectMsg("hello");
+ }
+}