egametang/ET · error · RpcException
ERR_ActorLocationSenderTimeout4
ERR_ActorLocationSenderTimeout4
Error message
{requestType.FullName} What it means
In CallInner's ERR_NotFoundActor retry path, the code waits with quadratic backoff (WaitAsync(failTimes * failTimes * 10)). After the backoff await, messageLocationSender was re-acquired from EntityRef and found null — the sender was disposed during the backoff wait. The cumulative backoff across retries grew long enough for the sender to time out.
Source
Thrown at Packages/cn.etetet.actorlocation/Scripts/Hotfix/Server/MessageLocationSenderComponentSystem.cs:300
{
Log.Debug($"actor send message fail, actorid: {messageLocationSender.Id} {requestType.FullName}");
// 这里删除actor,后面等待发送的消息会判断InstanceId,InstanceId不一致返回ERR_NotFoundActor
self = selfRef;
if (self != null)
{
self.Remove(messageLocationSender.Id);
}
return response;
}
// 等待0.5s再发送
root = rootRef;
await root.TimerComponent.WaitAsync(failTimes * failTimes * 10);
messageLocationSender = messageLocationSenderRef;
if (messageLocationSender == null)
{
throw new RpcException(ErrorCode.ERR_ActorLocationSenderTimeout4, $"{requestType.FullName}");
}
messageLocationSender.ActorId = default;
continue;
}
case ErrorCode.ERR_MessageTimeout:
{
throw new RpcException(response.Error, $"{requestType.FullName}");
}
}
if (ErrorCode.IsRpcNeedThrowException(response.Error))
{
throw new RpcException(response.Error, $"Message: {response.Message} Request: {requestType.FullName}");
}
return response;
}View on GitHub (pinned to 5cab01f7a8)
Solutions
- Catch RpcException with ERR_ActorLocationSenderTimeout4.
- Ensure the actor's location is registered before sending to avoid NotFoundActor.
- Stabilize actor placement to prevent migration churn.
- Investigate why the target actor is unreachable (crashed, wrong scene, not yet started).
Defensive patterns
Strategy: try-catch
Try / catch
try
{
IResponse resp = await senderOneType.Call(entityId, iLocationRequest);
}
catch (RpcException e) when (e.Error == ErrorCode.ERR_ActorLocationSenderTimeout4)
{
// Sender disposed during backoff wait — retry
IResponse resp = await senderOneType.Call(entityId, iLocationRequest);
} Prevention
- Ensure the actor's location is registered before sending to avoid NotFoundActor retries.
- Stabilize actor placement to prevent migration churn.
- Investigate why the target is repeatedly returning NotFoundActor.
When it happens
Trigger: Call(entityId, iLocationRequest) where the target returns ERR_NotFoundActor repeatedly, triggering retry with quadratic backoff, and the sender is disposed during a WaitAsync call.
Common situations: Actor migration in progress causing repeated NotFoundActor. Long NotFoundActor retry chains (up to 10 iterations). Sender times out during cumulative backoff (10+40+90+160+250+... ms).
Related errors
- ERR_ActorLocationSenderTimeout3
- ERR_MessageTimeout
- ERR_ActorLocationSenderTimeout2
- Message: {response.Message} Request: {requestType.FullName}
- ERR_LocationGetRetry
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/e74fef13e9dac227.
Report an issue: GitHub.