{"record":{"id":"bc1bdfda54fc5021","repo":"JuliusBrussee/caveman","slug":"upstream-body-exceeds-d-bytes","errorCode":null,"errorMessage":"upstream body exceeds %d bytes","messagePattern":"upstream body exceeds (.+?) bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/internal/gateway/proxy.go","lineNumber":1573,"sourceCode":"\nfunc labelOrDefault(v, fallback string) string {\n\tif v == \"\" {\n\t\treturn fallback\n\t}\n\treturn v\n}\n\n// readUpstreamBody drains a non-streaming upstream body in full. The cap only\n// bounds memory; a provider JSON document never approaches it.\nfunc readUpstreamBody(resp *http.Response) ([]byte, error) {\n\tdefer resp.Body.Close()\n\tlimit := int64(env.Int(\"CAVE_MAX_RESPONSE_BUFFER_BYTES\", 64<<20))\n\tdata, err := io.ReadAll(io.LimitReader(resp.Body, limit+1))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif int64(len(data)) > limit {\n\t\treturn nil, fmt.Errorf(\"upstream body exceeds %d bytes\", limit)\n\t}\n\treturn data, nil\n}\n\ntype countingWriter struct {\n\tw           http.ResponseWriter\n\tn           int64\n\tfirstByteAt time.Time\n}\n\nfunc (c *countingWriter) Write(p []byte) (int, error) {\n\tif c.firstByteAt.IsZero() && len(p) > 0 {\n\t\tc.firstByteAt = time.Now()\n\t}\n\tn, err := c.w.Write(p)\n\tc.n += int64(n)\n\treturn n, err\n}","sourceCodeStart":1555,"sourceCodeEnd":1591,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/df2ccd85c94ec3c8289cb62ac020d241ccfb0c60/proxy/internal/gateway/proxy.go#L1555-L1591","documentation":"readUpstreamBody enforces CAVE_MAX_RESPONSE_BUFFER_BYTES (default 64 MiB) as a memory bound when draining a non-streaming upstream response; a body over the cap is refused rather than buffered unbounded. Provider JSON never legitimately approaches this limit.","triggerScenarios":"Thrown at proxy/internal/gateway/proxy.go:1576 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Raise CAVE_MAX_RESPONSE_BUFFER_BYTES if legitimately huge responses are expected","Use streaming mode for responses that exceed the buffer cap"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"df2ccd85c94ec3c8289cb62ac020d241ccfb0c60","analyzedAt":"2026-08-27T02:25:50.681Z","contentChangedAt":"2026-08-27T02:25:50.681Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}