babalae/better-genshin-impact · error · InvalidDataException
未知命名管道载荷类型:{header[sizeof(uint)]}。
Error message
未知命名管道载荷类型:{header[sizeof(uint)]}。 What it means
Thrown by ReadFrameAsync after the payload length check passes. The 5th byte of the frame header is cast to InstanceIpcPayloadType and validated via Enum.IsDefined. If the byte value is not 1 (Utf8Json), 2 (RelativeMouseBatch), or 3 (RelativeMouseResult), the frame type is unrecognized and rejected.
Source
Thrown at BetterGenshinImpact/Service/Instance/InstanceIpcProtocol.cs:304
{
var header = new byte[FrameHeaderLength];
var firstRead = await stream.ReadAsync(header.AsMemory(0, 1), cancellationToken).ConfigureAwait(false);
if (firstRead == 0)
{
return null;
}
await stream.ReadExactlyAsync(header.AsMemory(1), cancellationToken).ConfigureAwait(false);
var payloadLength = BinaryPrimitives.ReadUInt32LittleEndian(header);
if (payloadLength > MaxPayloadLength)
{
throw new InvalidDataException($"命名管道消息超过 {MaxPayloadLength} 字节限制。");
}
var payloadType = (InstanceIpcPayloadType)header[sizeof(uint)];
if (!Enum.IsDefined(payloadType))
{
throw new InvalidDataException($"未知命名管道载荷类型:{header[sizeof(uint)]}。");
}
var payload = new byte[checked((int)payloadLength)];
if (payload.Length > 0)
{
await stream.ReadExactlyAsync(payload, cancellationToken).ConfigureAwait(false);
}
return new InstanceIpcFrame(payloadType, payload);
}
private static async ValueTask WriteFrameAsync(
Stream stream,
InstanceIpcPayloadType payloadType,
ReadOnlyMemory<byte> payload,
CancellationToken cancellationToken)
{
if (payload.Length > MaxPayloadLength)View on GitHub (pinned to a7cb36712d)
Solutions
- Ensure all BetterGI instances (Primary, ChildSession, WebView) in the same user session run the same application version.
- Catch InvalidDataException in the receive loop and dispose the connection to trigger a clean reconnect.
- Log the raw type byte value alongside the frame to identify whether it is a version issue (consistent new value) or corruption (random values).
- If developing a new payload type, update InstanceIpcPayloadType in all peers before deploying.
Defensive patterns
Strategy: try-catch
Type guard
// Check if a payload type byte is a known type
static bool IsKnownPayloadType(byte typeByte)
=> Enum.IsDefined((InstanceIpcPayloadType)typeByte); Try / catch
try
{
var frame = await InstanceIpcProtocol.ReadFrameAsync(stream, ct);
}
catch (InvalidDataException ex) when (ex.Message.Contains("未知命名管道载荷类型"))
{
_logger.LogError(ex, "收到未知帧类型,可能是版本不兼容,关闭连接");
await connection.DisposeAsync();
} Prevention
- Run all BetterGI instances in the same user session at the same version.
- Update InstanceIpcPayloadType in all peers before deploying a new frame type.
- Close the connection on unknown frame types — do not attempt to skip or resync the stream manually.
When it happens
Trigger: The payload type byte in the frame header is 0 or >= 4. This occurs when a newer protocol version introduced a new payload type that this receiver does not know about, when the stream is misaligned so a payload data byte is interpreted as the type field, or when the pipe buffer contains residual data from a crashed previous session.
Common situations: Running mixed versions of BetterGI where one side was updated to send a new frame type; stream misalignment caused by a bug in the receive loop reading the wrong number of bytes; a security tool or pipe relay injecting or dropping bytes; Windows named pipe kernel buffer not fully flushed after a previous process crash.
Related errors
- 相对鼠标处理结果帧无效。
- 命名管道消息超过 {MaxPayloadLength} 字节限制。
- 预期相对鼠标处理结果帧,实际为 {frame.PayloadType}。
- 根实例拒绝连接。
- 根实例连接响应缺少数据。
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/857c83ebc2ca0851.
Report an issue: GitHub.