socketio/socket.io · error · Error
illegal attachments
Error message
illegal attachments
What it means
Thrown by reconstructPacket/_reconstructPacket in the parser's binary module when a placeholder object's num field is not a valid index into the buffers array (it is not a number, is negative, or is >= buffers.length). During binary packet reconstruction each {_placeholder:true,num:N} marker is replaced by buffers[N]; an out-of-range N means the buffers and placeholders are out of sync.
Source
Thrown at packages/socket.io-parser/lib/binary.ts:74
export function reconstructPacket(packet, buffers) {
packet.data = _reconstructPacket(packet.data, buffers);
delete packet.attachments; // no longer useful
return packet;
}
function _reconstructPacket(data, buffers) {
if (!data) return data;
if (data && data._placeholder === true) {
const isIndexValid =
typeof data.num === "number" &&
data.num >= 0 &&
data.num < buffers.length;
if (isIndexValid) {
return buffers[data.num]; // appropriate buffer (should be natural order anyway)
} else {
throw new Error("illegal attachments");
}
} else if (Array.isArray(data)) {
for (let i = 0; i < data.length; i++) {
data[i] = _reconstructPacket(data[i], buffers);
}
} else if (typeof data === "object") {
for (const key in data) {
if (Object.prototype.hasOwnProperty.call(data, key)) {
data[key] = _reconstructPacket(data[key], buffers);
}
}
}
return data;
}
View on GitHub (pinned to ae7fb46e08)
Solutions
- Ensure the transport/adapter reliably delivers every binary attachment in order before reconstructPacket is called.
- If you construct packets manually, verify every {_placeholder:true,num} references a valid index (0 <= num < buffers.length).
- Upgrade encoder and decoder together so the placeholder/buffer contract matches.
Example fix
// before
const packet = reconstructPacket(rawPacket, partialBuffers); // throws if num out of range
// after
const expected = rawPacket.attachments || 0;
if (partialBuffers.length < expected) {
throw new Error(`missing ${expected - partialBuffers.length} binary attachments`);
}
const packet = reconstructPacket(rawPacket, partialBuffers); Defensive patterns
Strategy: validation
Validate before calling
function placeholdersOk(packet, buffers){
let ok=true;
(function walk(d){
if(d && d._placeholder===true){ if(!(typeof d.num==='number'&&d.num>=0&&d.num<buffers.length)) ok=false; return; }
if(Array.isArray(d)) d.forEach(walk); else if(d&&typeof d==='object') Object.keys(d).forEach(k=>walk(d[k]));
})(packet.data);
return ok;
} Type guard
function hasAllAttachments(packet, buffers){
return (packet.attachments||0) <= buffers.length;
} Try / catch
if(!placeholdersOk(rawPacket, buffers)){ throw new Error('illegal attachments: missing buffers'); }
const packet = reconstructPacket(rawPacket, buffers); Prevention
- Verify buffers.length >= declared attachments before reconstructing.
- Use a reliable transport/adapter that preserves binary frame order.
- Keep encoder and decoder on the same protocol version.
When it happens
Trigger: Reconstructing a binary packet whose placeholder references a buffer index that was never received, or where fewer binary attachments were supplied than the packet declared. Also triggered by hand-crafted/corrupted packets with bogus num values.
Common situations: A network/proxy dropping one of the binary attachment frames between the BINARY_EVENT header and the final buffer; a custom adapter that reorders or drops buffers; or a version mismatch between encoder and decoder that changes the placeholder format.
Related errors
- Illegal attachments
- too many attachments
- unknown event name: ${eventName}
- got plaintext data when reconstructing a packet
- got binary data when not reconstructing a packet
AI-assisted analysis of socketio/socket.io@ae7fb46e08 (2026-08-03).
Data as JSON: /data/errors/53ac34ff1f15cd20.json.
Report an issue: GitHub.