{"record":{"id":"da79cdcb6d1daaa8","repo":"egametang/ET","slug":"err-locationprimaryunavailable","errorCode":"ERR_LocationPrimaryUnavailable","errorMessage":"location service metadata missing scene: {serviceInfo?.SceneName}","messagePattern":"location service metadata missing scene: (.+?)","errorType":"exception","errorClass":"RpcException","httpStatus":null,"severity":"critical","filePath":"Packages/cn.etetet.actorlocation/Scripts/Hotfix/Server/LocationPrimaryHelper.cs","lineNumber":12,"sourceCode":"using System;\nusing System.Collections.Generic;\n\nnamespace ET.Server\n{\n    public static class LocationPrimaryHelper\n    {\n        public static ulong GetPriorityId(ServiceInfo serviceInfo)\n        {\n            if (serviceInfo?.Metadata == null)\n            {\n                throw new RpcException(ErrorCode.ERR_LocationPrimaryUnavailable,\n                    $\"location service metadata missing scene: {serviceInfo?.SceneName}\");\n            }\n\n            if (!serviceInfo.Metadata.TryGetValue(ServiceMetaKey.PriorityId, out string rawPriorityId)\n                || string.IsNullOrWhiteSpace(rawPriorityId))\n            {\n                throw new RpcException(ErrorCode.ERR_LocationPrimaryUnavailable,\n                    $\"location service priority missing scene: {serviceInfo.SceneName}\");\n            }\n\n            if (ulong.TryParse(rawPriorityId, out ulong priorityId))\n            {\n                return priorityId;\n            }\n\n            if (!long.TryParse(rawPriorityId, out long signedPriorityId))\n            {\n                throw new RpcException(ErrorCode.ERR_LocationPrimaryUnavailable,","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.actorlocation/Scripts/Hotfix/Server/LocationPrimaryHelper.cs#L1-L30","documentation":"Thrown by LocationPrimaryHelper.GetPriorityId when the ServiceInfo object is null or its Metadata dictionary is null. Every Location scene must register with service discovery carrying a Metadata dictionary that includes PriorityId (set in FiberInit_Location.cs:24-27). A null ServiceInfo or null Metadata means the registration was malformed or incomplete.","triggerScenarios":"GetPriorityId(serviceInfo) is called during SelectStablePrimaryServiceInfo when iterating discovered Location scenes, and one of them has a null Metadata. This propagates through GetPrimaryLocationSceneName in the proxy, which catches it as ERR_LocationPrimaryUnavailable and retries/clears primary.","commonSituations":"A Location scene registered with service discovery but its Metadata was not populated (custom FiberInit that skips the Metadata setup); a corrupted or partial ServiceInfo entity deserialized from DB/network with Metadata lost; version mismatch where an older client registers without Metadata.","solutions":["Ensure every Location scene's FiberInit registers with Metadata containing PriorityId, as FiberInit_Location.cs:24-27 does.","Check service discovery registration logs to verify Metadata was included.","If a node is registering with incomplete metadata, fix its FiberInit or registration call before it joins the cluster."],"exampleFix":"// before -- registration without metadata\nawait serviceDiscoveryProxy.RegisterToServiceDiscovery(new StringKV());\n\n// after -- include PriorityId in metadata\nawait serviceDiscoveryProxy.RegisterToServiceDiscovery(new StringKV\n{\n    { ServiceMetaKey.PriorityId, locationComponent.Id.ToString() }\n});","handlingStrategy":"validation","validationCode":"// Validate ServiceInfo before primary election\nforeach (ServiceInfo si in serviceInfos)\n{\n    if (si?.Metadata == null)\n    {\n        Log.Error($\"Location scene {si?.SceneName} has null metadata -- skipping\");\n        continue;\n    }\n}","typeGuard":"static bool HasValidMetadata(ServiceInfo si) => si?.Metadata != null;","tryCatchPattern":"try\n{\n    string primary = locationProxy.GetPrimaryLocationSceneName();\n}\ncatch (RpcException e) when (e.Error == ErrorCode.ERR_LocationPrimaryUnavailable)\n{\n    Log.Error($\"Primary election failed: {e.Message}\");\n}","preventionTips":["Ensure FiberInit_Location runs on every Location scene -- it sets Metadata with PriorityId.","Validate service discovery entries after registration to catch missing metadata early.","Monitor service discovery for entries with null or incomplete metadata."],"tags":["location","primary-election","service-discovery","configuration","metadata"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}