egametang/ET · error · Exception
actor id is 0: {message}
Error message
actor id is 0: {message} What it means
ProcessOuterSender.SendInner refuses to send a message when actorId is default (zero). ProcessOuterSender is the cross-process outer channel — unlike the inner sender it never routes locally, so a zero id cannot be resolved to any session. This is a hard precondition check before a Session lookup and Send.
Source
Thrown at Packages/cn.etetet.netinner/Scripts/Hotfix/Server/ProcessOuterSenderSystem.cs:194
if (self.NeedException && ErrorCode.IsRpcNeedThrowException(response.Error))
{
self.SetException(new RpcException(response.Error, $"Rpc error: actorId: {self.ActorId} request: {self.RequestType.FullName}, response: {response}"));
return;
}
self.SetResult(response);
}
public static void Send(this ProcessOuterSender self, ActorId actorId, IMessage message)
{
self.SendInner(actorId, message as MessageObject);
}
private static void SendInner(this ProcessOuterSender self, ActorId actorId, MessageObject message)
{
if (actorId == default)
{
throw new Exception($"actor id is 0: {message}");
}
if (message == null)
{
throw new Exception($"message is null");
}
// 如果发向同一个进程,则报错
if (actorId.Address == self.GetSingleton<AddressSingleton>().InnerAddress)
{
throw new Exception($"actor is the same process: {actorId}");
}
Session session = self.Get(actorId.Address);
session.Send(actorId.FiberInstanceId, message);
}
private static int GetRpcId(this ProcessOuterSender self)
{View on GitHub (pinned to 5cab01f7a8)
Solutions
- Log the actorId and its source (which config entry or look-up produced it) at the call site.
- Confirm the target process is declared in the process/address configuration and its address is registered.
- Guard the send with an actorId == default check and skip or queue the message.
Example fix
// before
outerSender.Send(actorId, msg);
// after
if (actorId == default)
{
Log.Error($"cannot Send, actorId is zero for {msg}");
return;
}
outerSender.Send(actorId, msg); Defensive patterns
Strategy: validation
Validate before calling
if (actorId == default) { Log.Error($"cannot Send, actorId is zero for {message}"); return; } Prevention
- Validate ActorId is non-default before any ProcessOuterSender.Send.
- Confirm the target process address is configured for the scene type.
- Centralize address resolution so missing entries log clearly.
When it happens
Trigger: Calling ProcessOuterSender.Send(actorId, message) with an ActorId that was never populated; resolving an address from a config/map that returned default for an unknown process.
Common situations: The caller assumed an outer process address exists but it was not configured in the start config; the ActorId field on an entity/component was not initialized before a send; a message was routed based on a player/guild id whose process mapping is missing.
Related errors
- actor id is 0: {request}
- actor id is 0: {iRequest}
- Rpc error: request, 注意Actor消息超时,请注意查看是否死锁或者没有reply: actorId:
- Rpc error: actorId: {actorId} {request}, response: {response
- message is null
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/44826c123852bcbe.
Report an issue: GitHub.