babalae/better-genshin-impact · error · InvalidOperationException

只有根实例可以向 BetterGI 客户端分发激活消息。

Error message

只有根实例可以向 BetterGI 客户端分发激活消息。

What it means

Thrown by HandleActivationDispatch when the current instance is Primary (it sends dispatches, it should not receive them) OR when the requesting connection's RemoteEndpoint is not Primary (activation.dispatch must originate from the root). This enforces the directional contract: activation messages flow strictly from Primary to ChildSession.

Source

Thrown at BetterGenshinImpact/Service/Instance/MessageHandlers/InstanceRequestHandler.cs:113

            _logger.LogWarning(exception, "处理实例 IPC 请求失败:{Operation}", request.Operation);
            return InstanceIpcEnvelope.Failure(
                request,
                "invalid_request",
                exception.GetBaseException().Message);
        }
    }

    /// <summary>
    /// 激活消息按 RequestId 去重,避免管道重试导致主窗口被重复激活。
    /// </summary>
    private InstanceIpcEnvelope HandleActivationDispatch(
        InstanceConnection connection,
        InstanceIpcEnvelope request)
    {
        if (_context.InstanceType == BetterGiInstanceType.Primary
            || connection.RemoteEndpoint?.InstanceType != BetterGiInstanceType.Primary)
        {
            throw new InvalidOperationException("只有根实例可以向 BetterGI 客户端分发激活消息。");
        }

        if (_activationResponses.TryGetValue(request.RequestId, out var cachedResponse))
        {
            return cachedResponse;
        }

        var activation =
            request.Data?.ToObject<ActivationDispatchRequest>(InstanceIpcProtocol.Serializer)
            ?? throw new ArgumentException("激活请求缺少命令行参数。");
        _enqueueActivation(activation.Arguments);
        return CacheActivationResponse(
            request.RequestId,
            InstanceIpcEnvelope.Response(request));
    }

    /// <summary>
    /// 校验子实例身份和启动记录后,将当前连接登记为有效子连接。

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Verify the root's HandleConnectionOpenAsync forwarding logic correctly targets ChildSession connections only when sending activation.dispatch.
  2. Ensure only ChildSession-type instances register as activation dispatch targets — check the _state.BetterGiConnectionsBySession registration.
  3. Catch this InvalidOperationException on the sending side (the root) and fall back to accepting the new connection directly rather than forwarding.
  4. Log connection.RemoteEndpoint?.InstanceType at the throw site to identify which peer type sent the invalid dispatch.
Defensive patterns

Strategy: validation

Validate before calling

// On the root side, before sending activation.dispatch, verify target is a ChildSession
if (connection.RemoteEndpoint?.InstanceType != BetterGiInstanceType.ChildSession)
{
    _logger.LogWarning("跳过激活转发:目标不是 ChildSession");
    return;
}

Type guard

// Check if a connection is authorized to receive activation dispatch
static bool CanReceiveActivationDispatch(InstanceContext context, InstanceConnection conn)
    => context.InstanceType != BetterGiInstanceType.Primary
       && conn.RemoteEndpoint?.InstanceType == BetterGiInstanceType.Primary;

Prevention

When it happens

Trigger: A non-Primary instance receives an activation.dispatch request from a connection whose remote endpoint is not Primary, or the Primary instance itself receives an activation.dispatch (which would be a loop). The check is: if (_context.InstanceType == Primary || connection.RemoteEndpoint?.InstanceType != Primary) throw. So Primary rejects inbound dispatches, and non-child instances reject dispatches from non-Primary peers.

Common situations: A misconfigured or malicious peer sends activation.dispatch to the wrong instance type; a protocol version mismatch causes the dispatcher to route activation.dispatch to a WebView instead of a ChildSession; a bug in the root's forwarding logic sends dispatch to the wrong target; a replayed or duplicated frame from a corrupt stream.

Related errors


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