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
- Verify the root's HandleConnectionOpenAsync forwarding logic correctly targets ChildSession connections only when sending activation.dispatch.
- Ensure only ChildSession-type instances register as activation dispatch targets — check the _state.BetterGiConnectionsBySession registration.
- Catch this InvalidOperationException on the sending side (the root) and fall back to accepting the new connection directly rather than forwarding.
- 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
- Ensure activation.dispatch is only sent to registered ChildSession connections.
- Verify the root's forwarding logic targets the correct instance type.
- Log RemoteEndpoint.InstanceType at the dispatch point to catch routing errors.
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
- 只有根实例可以接受客户端连接登记。
- WebView 不能向其他 WebView 发送消息。
- 根实例分配了不匹配的客户端类型:{openResponse.AssignedType}。
- 激活请求缺少命令行参数。
- 当前JS脚本不允许使用HTTP请求,请在调度器通用设置中启用“JS HTTP权限”
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/97a5ed81e76e9f41.
Report an issue: GitHub.