{"record":{"id":"c7ef36191c6c17bf","repo":"linera-io/linera-protocol","slug":"writer-limit-exceeded","errorCode":null,"errorMessage":"Writer limit exceeded","messagePattern":"Writer limit exceeded","errorType":"exception","errorClass":"LimitedWriterError","httpStatus":null,"severity":"error","filePath":"linera-base/src/limited_writer.rs","lineNumber":35,"sourceCode":"    limit: usize,\n    written: usize,\n}\n\nimpl<W: Write> LimitedWriter<W> {\n    pub fn new(inner: W, limit: usize) -> Self {\n        Self {\n            inner,\n            limit,\n            written: 0,\n        }\n    }\n}\n\nimpl<W: Write> Write for LimitedWriter<W> {\n    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n        // Calculate the number of bytes we can write without exceeding the limit.\n        // Fail if the buffer doesn't fit.\n        ensure!(\n            self.limit\n                .checked_sub(self.written)\n                .is_some_and(|remaining| buf.len() <= remaining),\n            io::Error::other(LimitedWriterError)\n        );\n        // Forward to the inner writer.\n        let n = self.inner.write(buf)?;\n        self.written += n;\n        Ok(n)\n    }\n\n    fn flush(&mut self) -> io::Result<()> {\n        self.inner.flush()\n    }\n}\n\n#[cfg(test)]\nmod tests {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-base/src/limited_writer.rs#L17-L53","documentation":"LimitedWriter wraps a std::io::Write and enforces a hard byte budget: each write checks that written + buf.len() stays within limit, using checked_sub so overflow also fails. Any single write that would cross the limit returns io::Error wrapping LimitedWriterError ('Writer limit exceeded') instead of a partial write, so the whole write is rejected.","triggerScenarios":"Serializing a value through a LimitedWriter (e.g. capping a JSON/bcs response payload) where the encoded output exceeds the limit; a single large write chunk crossing the remaining budget even though earlier writes fit.","commonSituations":"API/GraphQL response caps in linera services where a query returns more data than the configured cap; increasing an object's size (more chains, larger blobs) past a previously sufficient limit; tests using tiny limits (the unit test writes 6 bytes into a limit of 5).","solutions":["Raise the limit passed to LimitedWriter::new to fit the expected worst-case payload","Reduce the data being written: paginate the query, drop unnecessary fields, or split into multiple capped writes","Pre-compute the serialized size first and reject early with a clean error instead of failing mid-write"],"exampleFix":"// before\nlet mut w = LimitedWriter::new(&mut out, 1024); // payload is 2 KiB -> error\n\n// after\nlet bytes = serde_json::to_vec(&value)?;\nif bytes.len() > 1024 {\n    return Err(anyhow::anyhow!(\"response too large: {}\", bytes.len()));\n}\nout.write_all(&bytes)?;","handlingStrategy":"validation","validationCode":"// Size the payload before writing through the cap\nlet bytes = serde_json::to_vec(&response)?;\nif bytes.len() > LIMIT {\n    return Err(anyhow::anyhow!(\"payload {} B exceeds cap {} B\", bytes.len(), LIMIT));\n}\nwriter.write_all(&bytes)?;","typeGuard":null,"tryCatchPattern":"use linera_base::limited_writer::LimitedWriterError;\nmatch writer.write_all(&buf) {\n    Ok(()) => Ok(()),\n    Err(e) if e.get_ref().and_then(|r| r.downcast_ref::<LimitedWriterError>()).is_some() => {\n        Err(anyhow::anyhow!(\"response exceeded {LIMIT} byte cap; reduce payload\"))\n    }\n    Err(e) => Err(e.into()),\n}","preventionTips":["Set the limit from the actual worst-case payload, not a round number guessed later","Paginate or truncate large query results at the service layer instead of relying on the writer to fail","Unit-test the cap: assert oversized payloads are rejected with LimitedWriterError, not a partial write"],"tags":["io","writer","size-limit","dos-protection","rust"],"backgroundTag":"write-limit-exceeded","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}