{"id":"e958ac69e6b163c4","repo":"socketio/socket.io","slug":"got-plaintext-data-when-reconstructing-a-packet","errorCode":null,"errorMessage":"got plaintext data when reconstructing a packet","messagePattern":"got plaintext data when reconstructing a packet","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/socket.io-parser/lib/index.ts","lineNumber":185,"sourceCode":"      {\n        reviver: undefined,\n        maxAttachments: 10,\n      },\n      typeof opts === \"function\" ? { reviver: opts } : opts,\n    );\n  }\n\n  /**\n   * Decodes an encoded packet string into packet JSON.\n   *\n   * @param {String} obj - encoded packet\n   */\n\n  public add(obj: any) {\n    let packet;\n    if (typeof obj === \"string\") {\n      if (this.reconstructor) {\n        throw new Error(\"got plaintext data when reconstructing a packet\");\n      }\n      packet = this.decodeString(obj);\n      const isBinaryEvent = packet.type === PacketType.BINARY_EVENT;\n      if (isBinaryEvent || packet.type === PacketType.BINARY_ACK) {\n        packet.type = isBinaryEvent ? PacketType.EVENT : PacketType.ACK;\n        // binary packet's json\n        this.reconstructor = new BinaryReconstructor(packet);\n      } else {\n        // non-binary full packet\n        super.emitReserved(\"decoded\", packet);\n      }\n    } else if (isBinary(obj) || obj.base64) {\n      // raw binary data\n      if (!this.reconstructor) {\n        throw new Error(\"got binary data when not reconstructing a packet\");\n      } else {\n        packet = this.reconstructor.takeBinaryData(obj);\n        if (packet) {","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/socketio/socket.io/blob/ae7fb46e08c5ed964b4a1ea8b1703e816511598e/packages/socket.io-parser/lib/index.ts#L167-L203","documentation":"Thrown by the parser Decoder.add() when a plaintext (string) packet arrives while a BinaryReconstructor is already active. Once a BINARY_EVENT/BINARY_ACK packet has been received, the decoder expects only binary attachments until reconstruction completes; an intervening string frame breaks the stream protocol.","triggerScenarios":"The decoder receives a BINARY_EVENT packet (setting up a reconstructor) and then, before all declared attachments have arrived, receives another string-encoded packet via add().","commonSituations":"A buggy transport multiplexing frames out of order, a proxy/gateway that injects a ping or text frame into the stream, or a custom client that feeds interleaved string and binary data to the same Decoder instance.","solutions":["Ensure the transport delivers frames in strict order: the BINARY_EVENT string packet followed by exactly its N binary attachments before any other string packet.","If using a multiplexed/interleaved source, give each logical packet its own Decoder instance.","Call decoder.destroy() to reset a stuck reconstructor before feeding fresh data."],"exampleFix":"// before\ndecoder.add(binaryEventString);\n// stray string arrives mid-reconstruction\ndecoder.add(anotherStringPacket); // throws\n\n// after\ndecoder.add(binaryEventString);\n// wait for all attachments; only then accept new string packets\ndecoder.add(buf1); decoder.add(buf2);\n// reconstruction done, safe to feed next string packet\ndecoder.add(anotherStringPacket);","handlingStrategy":"validation","validationCode":"function canAcceptString(decoder){ return !decoder.reconstructor; }","typeGuard":"function isReconstructing(decoder){ return !!decoder.reconstructor; }","tryCatchPattern":"try { decoder.add(str); }\ncatch(e){ if(/plaintext data when reconstructing/.test(e.message)){ decoder.destroy(); decoder.add(str);} else throw e; }","preventionTips":["Ensure strict frame ordering: BINARY_EVENT header then its attachments.","Use one Decoder per interleaved logical packet stream.","Call decoder.destroy() to reset a stuck reconstructor before fresh input."],"tags":["parser","binary","protocol","decoder"],"analyzedSha":"ae7fb46e08c5ed964b4a1ea8b1703e816511598e","analyzedAt":"2026-08-03T19:08:14.127Z","schemaVersion":2}