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

  1. 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.
  2. If the root is genuinely gone, the retry loop will keep failing — investigate why the root process exited (check Windows Event Log, BetterGI logs).
  3. If this occurs during shutdown, ensure the lifetime CancellationToken is being cancelled cleanly and the catch for OperationCanceledException suppresses the warning.
  4. 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

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


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/046d1980d4a08f0a. Report an issue: GitHub.