{"record":{"id":"05329e6d6508903d","repo":"golang/go","slug":"bytes-buffer-grow-negative-count","errorCode":null,"errorMessage":"bytes.Buffer.Grow: negative count","messagePattern":"bytes\\.Buffer\\.Grow: negative count","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/bytes/buffer.go","lineNumber":184,"sourceCode":"\t\tpanic(ErrTooLarge)\n\t} else {\n\t\t// Add b.off to account for b.buf[:b.off] being sliced off the front.\n\t\tb.buf = growSlice(b.buf[b.off:], b.off+n)\n\t}\n\t// Restore b.off and len(b.buf).\n\tb.off = 0\n\tb.buf = b.buf[:m+n]\n\treturn m\n}\n\n// Grow grows the buffer's capacity, if necessary, to guarantee space for\n// another n bytes. After Grow(n), at least n bytes can be written to the\n// buffer without another allocation.\n// If n is negative, Grow will panic.\n// If the buffer can't grow it will panic with [ErrTooLarge].\nfunc (b *Buffer) Grow(n int) {\n\tif n < 0 {\n\t\tpanic(\"bytes.Buffer.Grow: negative count\")\n\t}\n\tm := b.grow(n)\n\tb.buf = b.buf[:m]\n}\n\n// Write appends the contents of p to the buffer, growing the buffer as\n// needed. The return value n is the length of p; err is always nil. If the\n// buffer becomes too large, Write will panic with [ErrTooLarge].\nfunc (b *Buffer) Write(p []byte) (n int, err error) {\n\tb.lastRead = opInvalid\n\tm, ok := b.tryGrowByReslice(len(p))\n\tif !ok {\n\t\tm = b.grow(len(p))\n\t}\n\treturn copy(b.buf[m:], p), nil\n}\n\n// WriteString appends the contents of s to the buffer, growing the buffer as","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/bytes/buffer.go#L166-L202","documentation":"Buffer.Grow(n) reserves space so that at least n more bytes can be written without reallocation. It panics with \"bytes.Buffer.Grow: negative count\" when n < 0, before any growth arithmetic. This is a pure input-validation panic; a successful Grow still may later panic with ErrTooLarge if the buffer cannot grow (delegated to grow).","triggerScenarios":"Calling b.Grow(n) with a negative n; computing n as a difference (a - b) that underflows when b > a; forwarding a size from a parsed field that was not range-checked; off-by-one where n = desired - current with current > desired.","commonSituations":"Pre-sizing a Buffer from user-controlled length fields; a Grow(capacity - b.Len()) where capacity < b.Len() after a reset/reuse miscalculation; size computed from a header that can legitimately be smaller than the current buffer.","solutions":["Validate n >= 0 before calling Grow.","If computing n as a difference, clamp to a floor of 0 (and decide whether 0 is meaningful; Grow(0) is a no-op-equivalent but allowed).","When pre-sizing from external input, range-check against both 0 and a sane upper bound before Grow."],"exampleFix":"// before\nwant := targetCap - b.Len() // can be negative\nb.Grow(want)\n\n// after\nwant := targetCap - b.Len()\nif want < 0 {\n    want = 0\n}\nb.Grow(want)","handlingStrategy":"validation","validationCode":"// Grow only with a non-negative size.\nfunc safeGrow(b *bytes.Buffer, n int) error {\n    if n < 0 {\n        return fmt.Errorf(\"grow count %d must be >= 0\", n)\n    }\n    b.Grow(n)\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Range-check any externally sourced growth size before calling Grow.","When computing n as a difference, clamp the floor at 0.","Treat Grow(0) as a no-op; never let arithmetic produce a negative n silently."],"tags":["bytes","buffer","validation","panic","go","grow"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}