babalae/better-genshin-impact · warning · IOException
根实例连接在完成登记前已经关闭。
Error message
根实例连接在完成登记前已经关闭。
What it means
Thrown in RootConnectionLoopAsync when the root connection's Completion task is already completed immediately after sending the connection.open request and starting the connection. This means the pipe connection to the root broke in the narrow window between the open handshake response and the registration step (setting _rootConnection). An IOException is used (not InvalidDataException) because the root cause is a transport failure, not a protocol violation.
Source
Thrown at BetterGenshinImpact/Service/Instance/InstanceService.cs:461
throw new InvalidOperationException(
$"根实例分配了不匹配的客户端类型:{openResponse.AssignedType}。");
}
Context.SetRootSessionId(openResponse.RootSessionId);
connection.RemoteEndpoint = new InstanceEndpoint
{
InstanceType = BetterGiInstanceType.Primary,
ProcessId = openResponse.RootProcessId,
WindowsSessionId = openResponse.RootSessionId,
StartedAt = DateTimeOffset.UtcNow
};
if (!connection.IsStarted)
{
connection.Start(cancellationToken);
}
if (connection.Completion.IsCompleted)
{
throw new IOException("根实例连接在完成登记前已经关闭。");
}
lock (_rootConnectionLock)
{
_rootConnection = connection;
}
includeActivationArguments = false;
restartFromProcessId = null;
_logger.LogInformation(
"已连接 BetterGI 根实例:进程 {ProcessId},Session {SessionId}",
openResponse.RootProcessId,
openResponse.RootSessionId);
if (Context.InstanceType == BetterGiInstanceType.ChildSession)
{
var subscribeResponse = await connection.SendRequestAsync(
InstanceOperations.RelativeMouseSubscribe,View on GitHub (pinned to a7cb36712d)
Solutions
- This is handled gracefully by the catch block for IOException in RootConnectionLoopAsync — the loop will log a warning and retry after ReconnectDelay (1 second). Ensure that catch block is intact.
- If the root is genuinely gone, the retry loop will keep failing — investigate why the root process exited (check Windows Event Log, BetterGI logs).
- If this occurs during shutdown, ensure the lifetime CancellationToken is being cancelled cleanly and the catch for OperationCanceledException suppresses the warning.
- Add logging of the Completion task's exception (if any) to diagnose why the receive loop terminated.
Defensive patterns
Strategy: retry
Try / catch
// Already handled by RootConnectionLoopAsync's IOException catch:
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException
or TimeoutException or OperationCanceledException or ObjectDisposedException)
{
_logger.LogWarning(exception, "连接根实例失败,稍后重试");
// Loop continues, retries after ReconnectDelay
} Prevention
- This is a transient transport failure — the reconnect loop handles it automatically.
- Ensure the root process is running and stable.
- Check Windows Event Log if the root keeps crashing during child connection.
When it happens
Trigger: After the child sends connection.open and receives a successful response, it calls connection.Start() (if not already started) and then checks connection.Completion.IsCompleted. If the receive loop already exited — because the root process exited, the pipe closed, or the CancellationToken fired — this fires. The window is extremely narrow: between receiving the open response and assigning _rootConnection.
Common situations: The root (Primary) process crashed or was killed immediately after responding to connection.open; the user shut down BetterGI while a child was connecting; a Windows session disconnect/logoff caused the pipe to close; a cancellation token from StopAsync fired during a reconnect cycle.
Related errors
- 根实例拒绝连接。
- 根实例连接响应缺少数据。
- 不支持的实例 IPC 版本:{envelope.Version}。
- 预期 JSON 帧,实际为 {frame.PayloadType}。
- 命名管道 JSON 消息为空。
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/046d1980d4a08f0a.
Report an issue: GitHub.