egametang/ET · error · Exception
actor id is 0: {request}
Error message
actor id is 0: {request} What it means
Thrown by MessageSender.Call when actorId equals default(ActorId), i.e. a zero/uninitialized actor id. The ET framework requires every Actor RPC to target a valid ActorId (process address + fiber instance id); a zero id means no destination was ever resolved. The guard fires before any network or intra-process dispatch, so it is a pure caller-contract violation.
Source
Thrown at Packages/cn.etetet.netinner/Scripts/Hotfix/Server/MessageSenderSystem.cs:45
a2NetInnerMessage.FromFiber = fiber.Id;
a2NetInnerMessage.ActorId = actorId;
a2NetInnerMessage.MessageObject = message;
FiberInstanceId netInnerFiberInstanceId = self.GetSingleton<ProcessFiberAddressSingleton>().Get(SceneType.NetInner);
MessageQueue.Instance.Send(fiber, netInnerFiberInstanceId, a2NetInnerMessage);
}
public static async ETTask<IResponse> Call(this MessageSender self, ActorId actorId, IRequest request, bool needException = true)
{
return await self.Call(actorId, request, ProcessInnerSender.TIMEOUT_TIME, needException);
}
public static async ETTask<IResponse> Call(this MessageSender self, ActorId actorId, IRequest request, long timeout,
bool needException = true)
{
if (actorId == default)
{
throw new Exception($"actor id is 0: {request}");
}
IResponse response;
if (actorId.Address == self.GetSingleton<AddressSingleton>().InnerAddress)
{
response = await self.ProcessInnerSender.Call(actorId.FiberInstanceId, request, timeout, needException);
}
else
{
// 发给NetInner纤程
A2NetInner_Request a2NetInner_Request = A2NetInner_Request.Create();
a2NetInner_Request.ActorId = actorId;
a2NetInner_Request.MessageObject = request;
FiberInstanceId netInnerFiberInstanceId = self.GetSingleton<ProcessFiberAddressSingleton>().Get(SceneType.NetInner);
using A2NetInner_Response a2NetInnerResponse = await self.ProcessInnerSender.Call(
netInnerFiberInstanceId, a2NetInner_Request, timeout) as A2NetInner_Response;
response = a2NetInnerResponse.MessageObject;View on GitHub (pinned to 5cab01f7a8)
Solutions
- Trace the call site: print/log the actorId value and the scene type or entity it was resolved from right before Call.
- Verify the target scene/fiber is actually running in this process or on the target process (check ProcessFiberAddressSingleton / address config).
- Replace the raw default with an explicit null-check or 'is target scene started?' guard before calling Call.
- Ensure server start order registers all SceneType fibers before any RPC depends on them.
Example fix
// before
MessageSender.Instance.Call(actorId, req);
// after
if (actorId == default)
{
Log.Error($"target ActorId is zero, cannot send {req}");
return;
}
MessageSender.Instance.Call(actorId, req); Defensive patterns
Strategy: validation
Validate before calling
if (actorId == default) { Log.Error($"ActorId is zero, aborting Call for {request}"); return; } Prevention
- Always resolve ActorId from ProcessFiberAddressSingleton and check it is non-default before calling Call.
- Log the source scene type when resolving addresses so missing scenes surface early.
- Ensure server startup registers all fibers before any RPC dependency.
When it happens
Trigger: Calling MessageSender.Call(actorId, request) where actorId was never assigned (still default), or where a look-up that should have produced an ActorId returned default (e.g. GetSingleton<ProcessFiberAddressSingleton>().Get(...) for a scene type that is not running in this process).
Common situations: A fiber/scene the caller assumes exists has not been started yet; a configuration file lists a scene type that was never spawned; the caller fetched an ActorId from a dictionary that had no entry and silently returned default; timing during server startup before all fibers register their addresses.
Related errors
- actor id is 0: {message}
- 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/a7074422dd7c71bf.
Report an issue: GitHub.