egametang/ET · error · Exception

location db manager not found scene: {root.Name}

Error message

location db manager not found scene: {root.Name}

What it means

Thrown by SelectServiceActorIdByRouteKey when the service list passed to route-key selection is null or empty. It is wrapped as RpcException(ERR_ServiceNotFound) so the CallBySceneTypeAsync retry loop (ShouldRetryServiceCallError returns true for ERR_ServiceNotFound) can trigger failover. It is the routing layer's invariant that at least one service instance exists before computing a consistent-hash index via GetRouteIndex.

Source

Thrown at Packages/cn.etetet.actorlocation/Scripts/Hotfix/Server/LocationComponentSystem.cs:138

                self.RemoveCachedInfo(key);
                return;
            }

            LocationInfo locationInfo = self.GetCachedInfo(key) ?? self.CreateInfo(key);
            locationInfo.TypeStates.Clear();
            foreach ((int locationType, LocationTypeState state) in snapshot)
            {
                locationInfo.TypeStates[locationType] = state;
            }
        }

        private static DBComponent GetDBComponent(this LocationComponent self)
        {
            Scene root = self.Root();
            DBManagerComponent dbManagerComponent = root.GetComponent<DBManagerComponent>();
            if (dbManagerComponent == null)
            {
                throw new Exception($"location db manager not found scene: {root.Name}");
            }

            return dbManagerComponent.GetZoneDB(root.Fiber.Zone);
        }

        private static async ETTask SaveInfoToDB(this LocationComponent self, LocationInfo locationInfo)
        {
            if (locationInfo == null)
            {
                return;
            }

            long key = locationInfo.Id;
            EntityRef<LocationComponent> selfRef = self;
            EntityRef<LocationInfo> locationInfoRef = locationInfo;
            DBComponent dbComponent = self.GetDBComponent();
            EntityRef<DBComponent> dbComponentRef = dbComponent;
            Scene root = self.Root();

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Ensure the provider scene for that sceneType is started and its registration reached this proxy before consumers call (check OnServiceChangeAddService logs for the sceneName).
  2. Verify the sceneType integer resolves to the same SceneType name on both registration and query via SceneTypeSingleton.Instance.GetSceneName(sceneType).
  3. Raise ServiceResolveRetryTimes / ServiceResolveRetryIntervalMs on the proxy so transient registration races resolve during the built-in retry loop.
  4. Pre-check with GetBySceneType(sceneType) and fall back / queue the request when Count == 0 instead of relying on the exception.

Example fix

// before
ActorId actorId = self.ResolveServiceActorIdByRouteKeyOnce(sceneType, sceneTypeName, routeKey);

// after
List<ServiceInfo> services = self.GetBySceneType(sceneType);
if (services == null || services.Count == 0)
{
    // defer or fail soft instead of letting routing throw
    return default;
}
ActorId actorId = self.ResolveServiceActorIdByRouteKeyOnce(sceneType, sceneTypeName, routeKey);
Defensive patterns

Strategy: retry

Validate before calling

List<ServiceInfo> services = proxy.GetBySceneType(sceneType);
if (services == null || services.Count == 0)
{
    // provider not registered yet; defer or fall back
    return;
}

Try / catch

try
{
    T resp = await proxy.CallBySceneTypeAsync<T>(sceneType, request, nameof(request), routeKey);
}
catch (RpcException ex) when (ex.Error == ErrorCode.ERR_ServiceNotFound)
{
    // exhaustive retries already attempted by the proxy; surface as service unavailable
    Log.Warning($"service not found for sceneType {sceneType}: {ex.Message}");
}

Prevention

When it happens

Trigger: Calling CallBySceneTypeAsync / ResolveServiceActorIdByRouteKeyOnce when no service of the target sceneType has registered with the ServiceDiscoveryProxy local cache (GetBySceneType returns 0 entries), or when every instance deregistered before the call resolved. ResolveServiceActorIdByRouteKeyOnce already guards Count==0 at line 408, so reaching line 433 means a concurrent mutation emptied the list between the check and SelectServiceActorIdByRouteKey.

Common situations: Target provider scene not started yet; service registered under a different sceneType metadata key than the query (SceneTypeSingleton.GetSceneName mismatch); startup race where the consumer calls before the provider registers; wrong zone filter narrowing the result to zero.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/f80a24b72dd74f2f. Report an issue: GitHub.