babalae/better-genshin-impact · error · InvalidDataException
命名管道消息超过 {MaxPayloadLength} 字节限制。
Error message
命名管道消息超过 {MaxPayloadLength} 字节限制。 What it means
Thrown by ReadFrameAsync (the receive side of the IPC framing layer). After reading the 5-byte frame header, it interprets the first 4 bytes as a little-endian uint32 payload length. If that value exceeds MaxPayloadLength (1,048,576 bytes = 1 MiB), the frame is rejected before any payload allocation occurs, protecting against denial-of-service via oversized length fields.
Source
Thrown at BetterGenshinImpact/Service/Instance/InstanceIpcProtocol.cs:298
span[sizeof(ulong)] == 1);
}
internal static async ValueTask<InstanceIpcFrame?> ReadFrameAsync(
Stream stream,
CancellationToken cancellationToken)
{
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(View on GitHub (pinned to a7cb36712d)
Solutions
- Catch InvalidDataException in the connection receive loop and close the pipe so the accept/reconnect loops establish a fresh stream.
- If sending large data through WebView messages, chunk or externalize the data (write to a temp file and pass a path) instead of embedding it in the IPC envelope.
- Verify protocol version match between peers — a header layout change will cause every length field to be misread.
- Add logging of the raw header bytes and decoded length at the throw site to distinguish genuine oversize from stream corruption.
Defensive patterns
Strategy: try-catch
Try / catch
// In the receive loop:
try
{
var frame = await InstanceIpcProtocol.ReadFrameAsync(stream, ct);
}
catch (InvalidDataException ex) when (ex.Message.Contains("字节限制"))
{
_logger.LogError(ex, "收到超大帧,关闭连接");
await connection.DisposeAsync();
} Prevention
- Never embed payloads > 1 MiB in IPC envelopes — use file-based transfer for large data.
- Ensure protocol version match so header layout is consistent.
- Close the connection on any frame validation failure to avoid cascade corruption.
When it happens
Trigger: The peer (or a corrupt/malicious stream) sent a frame whose 4-byte length header decodes to a value greater than 1 MiB. In normal operation this should never happen — JSON envelopes and mouse frames are far smaller. A genuinely oversized JSON envelope (e.g., a WebView message embedding a multi-megabyte data payload) could trigger it, but more commonly the length field is garbage from stream misalignment or a crashed peer leaving partial data in the pipe buffer.
Common situations: A previous frame was misread (wrong byte count consumed), shifting the stream so the parser interprets payload data or a JSON string as a length header; an older/newer protocol version uses a different header layout; an attempt to send a very large embedded data blob through SendWebViewMessageAsync that serialized to > 1 MiB of JSON.
Related errors
- 相对鼠标处理结果帧无效。
- 未知命名管道载荷类型:{header[sizeof(uint)]}。
- 预期相对鼠标处理结果帧,实际为 {frame.PayloadType}。
- 根实例拒绝连接。
- 根实例连接响应缺少数据。
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/cebe056738f479f2.
Report an issue: GitHub.