{"record":{"id":"9d42254d1a881f8e","repo":"egametang/ET","slug":"serviceagentregisterrequest-invalid-agentactorid","errorCode":null,"errorMessage":"ServiceAgentRegisterRequest invalid: AgentActorId is empty.","messagePattern":"ServiceAgentRegisterRequest invalid: AgentActorId is empty\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.servicediscovery/Scripts/Hotfix/Server/ServiceDiscoveryAgentSystem.cs","lineNumber":722,"sourceCode":"            if (self == null)\n            {\n                return false;\n            }\n\n            if (self.ServiceDiscoveryActorId == default)\n            {\n                return false;\n            }\n\n            EntityRef<ServiceDiscoveryAgent> selfRef = self;\n            ActorId targetActorId = self.ServiceDiscoveryActorId;\n            ServiceAgentRegisterRequest request = ServiceAgentRegisterRequest.Create();\n            request.AgentActorId = self.Root().GetActorId();\n            Address ownedAddress = request.AgentActorId.Address;\n            if (!ServiceDiscoveryHelper.TryValidateRequiredActorId(request.AgentActorId, nameof(ServiceAgentRegisterRequest),\n                    nameof(request.AgentActorId), out string errorMessage))\n            {\n                throw new ArgumentException(errorMessage);\n            }\n\n            self.AppendOwnedLocalServices(request);\n\n            try\n            {\n                TimerComponent timer = self.Root().TimerComponent;\n                ETTask<IResponse> registerTask = self.MessageSender.Call(targetActorId, request);\n                IResponse rawResponse = await registerTask;\n                self = selfRef;\n                if (self == null)\n                {\n                    (rawResponse as MessageObject)?.Dispose();\n                    return false;\n                }\n\n                if (rawResponse is not ServiceAgentRegisterResponse response)\n                {","sourceCodeStart":704,"sourceCodeEnd":740,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.servicediscovery/Scripts/Hotfix/Server/ServiceDiscoveryAgentSystem.cs#L704-L740","documentation":"ArgumentException thrown at line 722 in TryRegisterAgentToDiscoveryAsync: ServiceDiscoveryHelpers.TryValidateRequiredActorId failed because request.AgentActorId (set from self.Root().GetActorId()) is empty/default. The agent cannot register with the master without a valid own ActorId/address, so registration is rejected upfront.","triggerScenarios":"TriggerBackgroundRegister/TryRegisterAgentToDiscoveryAsync runs before the agent's Root Scene has a valid ActorId assigned — GetActorId() returns default because the scene/fiber identity is not yet initialized. Also possible if the scene's Process/Address is unset.","commonSituations":"Registration triggered too early in scene Awake (before ActorId is assigned); a scene created without a proper Address/Process binding; startup ordering where background registration fires during partial initialization.","solutions":["Defer TriggerBackgroundRegister until the scene has a valid ActorId (ensure Root().GetActorId() != default before registering).","Verify scene creation provides a concrete ProcessId/Address so GetActorId() is populated.","Move registration initiation to a later lifecycle hook where identity is guaranteed."],"exampleFix":"// before\npublic static void Awake(this ServiceDiscoveryAgent self)\n{\n    self.EnsureBackgroundRegisterStarted(); // may run before ActorId set\n}\n\n// after: guard registration on a valid ActorId\nif (self.Root().GetActorId() != default)\n{\n    self.EnsureBackgroundRegisterStarted();\n}","handlingStrategy":"validation","validationCode":"// Ensure the scene has a valid ActorId before triggering registration.\nif (self.Root().GetActorId() == default)\n{\n    Log.Warning(\"scene ActorId not yet assigned; deferring discovery registration\");\n    return; // retry later\n}","typeGuard":null,"tryCatchPattern":"catch (ArgumentException e) when (e.Message.Contains(\"AgentActorId is empty\"))\n{\n    Log.Warning($\"deferred registration, ActorId not ready: {e.Message}\");\n    // schedule a retry once the scene identity is set\n}","preventionTips":["Trigger registration only after the scene's ActorId/Address is initialized.","Move registration to a later lifecycle hook than Awake if identity is set later.","Verify scene creation binds a concrete ProcessId/Address."],"tags":["csharp","et-framework","service-discovery","lifecycle","initialization","validation","actor-model"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}