{"record":{"id":"44801ed6e1f876e0","repo":"babalae/better-genshin-impact","slug":"json-44801e","errorCode":null,"errorMessage":"命名管道 JSON 消息为空。","messagePattern":"命名管道 JSON 消息为空。","errorType":"exception","errorClass":"InvalidDataException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/Service/Instance/InstanceIpcProtocol.cs","lineNumber":144,"sourceCode":"        var payload = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(envelope, SerializerSettings));\n        await WriteFrameAsync(\n            stream,\n            InstanceIpcPayloadType.Utf8Json,\n            payload,\n            cancellationToken).ConfigureAwait(false);\n    }\n\n    internal static InstanceIpcEnvelope ReadJson(InstanceIpcFrame frame)\n    {\n        if (frame.PayloadType != InstanceIpcPayloadType.Utf8Json)\n        {\n            throw new InvalidDataException($\"预期 JSON 帧，实际为 {frame.PayloadType}。\");\n        }\n\n        return JsonConvert.DeserializeObject<InstanceIpcEnvelope>(\n                   Encoding.UTF8.GetString(frame.Payload),\n                   SerializerSettings)\n               ?? throw new InvalidDataException(\"命名管道 JSON 消息为空。\");\n    }\n\n    internal static async ValueTask WriteRelativeMouseBatchAsync(\n        Stream stream,\n        ulong firstSequence,\n        IReadOnlyList<RelativeMouseSample> samples,\n        CancellationToken cancellationToken)\n    {\n        if (samples.Count is <= 0 or > 64)\n        {\n            throw new ArgumentOutOfRangeException(nameof(samples), \"相对鼠标批次必须包含 1 到 64 个样本。\");\n        }\n\n        var payload = CreateRelativeMousePayload(firstSequence, samples);\n\n        await WriteFrameAsync(\n            stream,\n            InstanceIpcPayloadType.RelativeMouseBatch,","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Service/Instance/InstanceIpcProtocol.cs#L126-L162","documentation":"Thrown by InstanceIpcProtocol.ReadJson when JsonConvert.DeserializeObject<InstanceIpcEnvelope> returns null — the UTF-8 payload decoded to the JSON literal `null` (or produced an envelope that Newtonsoft maps to null), which is not a valid IPC envelope.","triggerScenarios":"The peer sent the JSON token `null` as the frame payload, or the serializer settings (NullValueHandling.Ignore combined with an all-null envelope) collapsed the result to null.","commonSituations":"A peer bug that serializes a null/default envelope; protocol corruption that yields a `null` token; a deserialization contract change that no longer maps the JSON to the envelope type.","solutions":["Restart both instances to re-establish the pipe.","Ensure both instances run the same build (serialization contract must match).","If reproducing, inspect the raw UTF-8 payload — a literal `null` token points to a peer-side bug in envelope construction."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    var envelope = InstanceIpcProtocol.ReadJson(frame.Value);\n}\ncatch (InvalidDataException ex) when (ex.Message.Contains(\"为空\"))\n{\n    logger.LogError(ex, \"Received null JSON envelope; peer bug or corruption\");\n}","preventionTips":["Run the same BetterGI build on both ends so the serialization contract matches.","Ensure peers never serialize a null/default envelope — the Request/Response factories always set Operation.","Restart instances to recover from transient corruption."],"tags":["ipc","protocol","serialization","named-pipe"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}