{"record":{"id":"bcb0f2ef405f7b40","repo":"copy/v86","slug":"stream-capacity-overflow-in-growableringbuffer-wri","errorCode":null,"errorMessage":"stream capacity overflow in GrowableRingbuffer.write(), package dropped","messagePattern":"stream capacity overflow in GrowableRingbuffer\\.write\\(\\), package dropped","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/browser/fake_network.js","lineNumber":98,"sourceCode":"        this.length = 0;\n        this.buffer = new Uint8Array(initial_capacity);\n    }\n\n    /**\n     * @param {Uint8Array} src_array\n     */\n    write(src_array)\n    {\n        const src_length = src_array.length;\n        const total_length = this.length + src_length;\n        let capacity = this.buffer.length;\n        if(capacity < total_length) {\n            dbg_assert(capacity > 0);\n            while(capacity < total_length) {\n                capacity *= 2;\n            }\n            if(this.maximum_capacity && capacity > this.maximum_capacity) {\n                throw new Error(\"stream capacity overflow in GrowableRingbuffer.write(), package dropped\");\n            }\n            const new_buffer = new Uint8Array(capacity);\n            this.peek(new_buffer);\n            this.tail = 0;\n            this.head = this.length;\n            this.buffer = new_buffer;\n        }\n        const buffer = this.buffer;\n\n        const new_head = this.head + src_length;\n        if(new_head > capacity) {\n            const i_split = capacity - this.head;\n            buffer.set(src_array.subarray(0, i_split), this.head);\n            buffer.set(src_array.subarray(i_split));\n        }\n        else {\n            buffer.set(src_array, this.head);\n        }","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/copy/v86/blob/180830d539dcc87db1a191febf6c914f516d102f/src/browser/fake_network.js#L80-L116","documentation":"GrowableRingbuffer.write() doubles its internal buffer capacity when incoming data exceeds the current capacity. If the required doubled capacity exceeds the buffer's maximum_capacity, the write is rejected with this error and the packet is dropped, preventing unbounded memory growth from a fast producer / slow consumer.","triggerScenarios":"Calling write() with data whose total_length exceeds current capacity and whose required doubled capacity exceeds this.maximum_capacity (non-zero). Happens when the ring buffer's maximum_capacity is set small and a large packet arrives, or when data accumulates without being peeked/consumed fast enough across many writes.","commonSituations":"Configuring a network adapter receive buffer too small for large frames (e.g. jumbo packets or big downloads); a stalled consumer (emulator paused, no read side polling) letting the buffer grow until the cap is hit.","solutions":["Increase the ring buffer's maximum_capacity when constructing/configuring it so it fits the largest expected burst or packet","Ensure the consumer drains the buffer promptly (poll peek/read regularly) so capacity doubling is never needed","Reduce the size of data written per call (chunk the packet) or check remaining capacity before writing and drop/backpressure early","Wrap write() in try/catch and treat the throw as 'packet dropped' — re-request or retransmit at a higher protocol layer"],"exampleFix":"// before\nconst buf = new GrowableRingbuffer(4096);\nbuf.set_maximum_capacity(8192);\nbuf.write(hugePacket); // throws if doubling needs > 8192\n// after\nconst buf = new GrowableRingbuffer(65536);\nbuf.set_maximum_capacity(1 << 20); // headroom for large bursts\nif (buf.length + hugePacket.length < buf.maximum_capacity) {\n    buf.write(hugePacket);\n} else {\n    // drop or backpressure\n}","handlingStrategy":"validation","validationCode":"function canWrite(ringbuf, data) {\n    const needed = Math.max(ringbuf.length + data.length, data.length);\n    let cap = ringbuf.buffer.length;\n    while (cap < needed) cap *= 2;\n    return !ringbuf.maximum_capacity || cap <= ringbuf.maximum_capacity;\n}\nif (canWrite(buf, packet)) buf.write(packet); else dropPacket(packet);","typeGuard":null,"tryCatchPattern":"try {\n    ringbuf.write(data);\n} catch (e) {\n    if (e.message.includes(\"stream capacity overflow\")) {\n    // packet dropped by design: escalate (grow cap / backpressure / retransmit)\n    onPacketDropped(data);\n    } else throw e;\n}","preventionTips":["Set maximum_capacity generously relative to the largest expected burst","Drain the buffer on a regular timer or IRQ instead of letting it accumulate","Track buffer length before writes and apply backpressure early","Log dropped packets so silent loss is visible"],"tags":["buffer","capacity","ringbuffer","network"],"backgroundTag":"buffer-capacity-overflow","analyzedSha":"180830d539dcc87db1a191febf6c914f516d102f","analyzedAt":"2026-08-31T22:39:37.599Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}