egametang/ET · error · Exception
service discovery agent disposed
Error message
service discovery agent disposed
What it means
Thrown at the very entry of EnsureReadyForRequestAsync (line 412): the ServiceDiscoveryAgent entity was disposed before the request could be validated. The ET framework tracks entities through EntityRef<T>, a weak handle that returns null once the entity's Scene/fiber is torn down. Because Dispose already ran on the agent, IsReady() cannot even be evaluated, so the call aborts immediately rather than dereferencing a dead object.
Source
Thrown at Packages/cn.etetet.servicediscovery/Scripts/Hotfix/Server/ServiceDiscoveryAgentSystem.cs:412
return false;
}
if (self.CurrentMasterEpoch <= 0)
{
self.CurrentMasterEpoch = 1;
}
self.SwitchToEndpoint(bootstrap.MasterActorId, "inheritable-endpoint");
return true;
}
private static async ETTask EnsureReadyForRequestAsync(this ServiceDiscoveryAgent self, string requestName)
{
EntityRef<ServiceDiscoveryAgent> selfRef = self;
self = selfRef;
if (self == null)
{
throw new Exception("service discovery agent disposed");
}
if (self.IsReady())
{
return;
}
int totalRetryCount = MasterResolveMaxRetryCountWhenEndpointUnavailable;
for (int retry = 0; retry < totalRetryCount; ++retry)
{
self = selfRef;
if (self == null)
{
throw new Exception("service discovery agent disposed");
}
if (!self.HasStatus(ServiceDiscoveryAgentStatus.Bootstrapping))
{View on GitHub (pinned to 5cab01f7a8)
Solutions
- Check agent.IsReady() and that the owning Scene is not disposing before issuing ForwardToDiscoveryByFailover; skip the call during shutdown.
- Ensure shutdown drains/cancels in-flight discovery requests (cancel the ETCancellationToken / fiber) before disposing the agent entity.
- If this surfaces as an unhandled exception during restart, confirm the restart sequence disposes the agent only after the main loop has stopped accepting new requests.
Example fix
// before
var resp = await agent.ForwardToDiscoveryByFailover<T>(req, nameof(req));
// after
if (agent == null || !agent.IsReady())
{
return; // shutting down, skip
}
var resp = await agent.ForwardToDiscoveryByFailover<T>(req, nameof(req)); Defensive patterns
Strategy: validation
Validate before calling
// Validate agent liveness AND readiness before forwarding.
public static bool CanForward(ServiceDiscoveryAgent agent)
{
return agent != null
&& agent.Root() != null
&& agent.IsReady(); // ServiceDiscoveryActorId != default && AgentRegistered
}
// usage
if (!CanForward(agent))
{
Log.Warning("discovery agent not ready/disposed, skipping request");
return;
} Try / catch
// Tolerate dispose during shutdown at the call boundary.
try
{
T resp = await agent.ForwardToDiscoveryByFailover<T>(req, name);
}
catch (Exception e) when (agent == null || IsShuttingDown)
{
Log.Warning($"discovery call aborted (agent disposed/shutdown): {e.Message}");
} Prevention
- Never issue discovery forwarding during scene/fiber shutdown; gate on a shutdown flag.
- Drain in-flight ForwardToDiscoveryByFailover calls before disposing the agent.
- Keep a strong reference only for the duration of a synchronous check; re-validate after every await.
When it happens
Trigger: ForwardToDiscoveryByFailover / any internal call that reaches EnsureReadyForRequestAsync is invoked on an agent whose Root Scene is already shutting down or has been removed from its Fiber. This specific throw fires on the first selfRef dereference, so the agent was dead before the method body began executing.
Common situations: Server shutdown sequence where an outstanding RPC or heartbeat callback still references the agent; a scene reload/fiber recycle that disposes the agent while a queued continuation runs; manual Dispose called from failover logic while a concurrent request was already dispatched.
Related errors
- ServiceAgentRegisterRequest invalid: AgentActorId is empty.
- ETTask does not allow call GetResult directly when task not
- TaskT_TransitionToFinal_AlreadyCompleted
- ERR_ServiceDiscoveryMasterUnavailable
- service discovery endpoint unavailable after resolve, reques
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/a7088bd0012aabd9.
Report an issue: GitHub.