{"record":{"id":"77f656605c324a88","repo":"grafana/k6","slug":"draining-upload-response-body-w","errorCode":null,"errorMessage":"draining upload response body: %w","messagePattern":"draining upload response body: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/storage/file_persister.go","lineNumber":113,"sourceCode":"func (r *RemoteFilePersister) Persist(ctx context.Context, path string, data io.Reader) (err error) {\n\tpsResp, err := r.requestPresignedURL(ctx, path)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"requesting presigned url: %w\", err)\n\t}\n\n\treq, err := newFileUploadRequest(ctx, psResp, data)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating upload request: %w\", err)\n\t}\n\n\tresp, err := r.httpClient.Do(req) //nolint:gosec\n\tif err != nil {\n\t\treturn fmt.Errorf(\"performing upload request: %w\", err)\n\t}\n\tdefer resp.Body.Close() //nolint:errcheck\n\n\tif _, err := io.Copy(io.Discard, resp.Body); err != nil {\n\t\treturn fmt.Errorf(\"draining upload response body: %w\", err)\n\t}\n\n\tif err := checkStatusCode(resp); err != nil {\n\t\treturn fmt.Errorf(\"uploading: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// requestPresignedURL will request a new presigned URL from the remote server\n// and returns a [PresignedURLResponse] that contains the presigned URL details.\nfunc (r *RemoteFilePersister) requestPresignedURL(ctx context.Context, path string) (PresignedURLResponse, error) {\n\tb, err := buildPresignedRequestBody(r.basePath, path)\n\tif err != nil {\n\t\treturn PresignedURLResponse{}, fmt.Errorf(\"building request body: %w\", err)\n\t}\n\n\treq, err := http.NewRequestWithContext(","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/storage/file_persister.go#L95-L131","documentation":"Raised in RemoteFilePersister.Persist when io.Copy(io.Discard, resp.Body) fails while draining the upload response body. Draining enables connection reuse; failure here means the response body could not be fully read — connection reset mid-body or a read timeout — even though the server may have accepted the upload. The drain error is treated as fatal for the persist call.","triggerScenarios":"Thrown at internal/js/modules/k6/browser/storage/file_persister.go:113 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the persist; the artifact may or may not have been uploaded","Check for proxies/load balancers that truncate response bodies","Verify network stability between k6 and the storage endpoint","If persistent, disable cloud artifact upload and use local storage"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}