{"record":{"id":"a7074422dd7c71bf","repo":"egametang/ET","slug":"actor-id-is-0-request","errorCode":null,"errorMessage":"actor id is 0: {request}","messagePattern":"actor id is 0: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.netinner/Scripts/Hotfix/Server/MessageSenderSystem.cs","lineNumber":45,"sourceCode":"            a2NetInnerMessage.FromFiber = fiber.Id;\n            a2NetInnerMessage.ActorId = actorId;\n            a2NetInnerMessage.MessageObject = message;\n\n            FiberInstanceId netInnerFiberInstanceId = self.GetSingleton<ProcessFiberAddressSingleton>().Get(SceneType.NetInner);\n            MessageQueue.Instance.Send(fiber, netInnerFiberInstanceId, a2NetInnerMessage);\n        }\n\n        public static async ETTask<IResponse> Call(this MessageSender self, ActorId actorId, IRequest request, bool needException = true)\n        {\n            return await self.Call(actorId, request, ProcessInnerSender.TIMEOUT_TIME, needException);\n        }\n\n        public static async ETTask<IResponse> Call(this MessageSender self, ActorId actorId, IRequest request, long timeout,\n            bool needException = true)\n        {\n            if (actorId == default)\n            {\n                throw new Exception($\"actor id is 0: {request}\");\n            }\n            \n            IResponse response;\n            if (actorId.Address == self.GetSingleton<AddressSingleton>().InnerAddress)\n            {\n                response = await self.ProcessInnerSender.Call(actorId.FiberInstanceId, request, timeout, needException);\n            }\n            else\n            {\n                // 发给NetInner纤程\n                A2NetInner_Request a2NetInner_Request = A2NetInner_Request.Create();\n                a2NetInner_Request.ActorId = actorId;\n                a2NetInner_Request.MessageObject = request;\n\n                FiberInstanceId netInnerFiberInstanceId = self.GetSingleton<ProcessFiberAddressSingleton>().Get(SceneType.NetInner);\n                using A2NetInner_Response a2NetInnerResponse = await self.ProcessInnerSender.Call(\n                    netInnerFiberInstanceId, a2NetInner_Request, timeout) as A2NetInner_Response;\n                response = a2NetInnerResponse.MessageObject;","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.netinner/Scripts/Hotfix/Server/MessageSenderSystem.cs#L27-L63","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nMessageSender.Instance.Call(actorId, req);\n\n// after\nif (actorId == default)\n{\n    Log.Error($\"target ActorId is zero, cannot send {req}\");\n    return;\n}\nMessageSender.Instance.Call(actorId, req);","handlingStrategy":"validation","validationCode":"if (actorId == default) { Log.Error($\"ActorId is zero, aborting Call for {request}\"); return; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["et-framework","actor-rpc","validation","network"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}