{"record":{"id":"97b4bc99bd2c755a","repo":"JuliusBrussee/caveman","slug":"transport-error","errorCode":"transport_error","errorMessage":"cachebench: provider transport failed for %q: %w","messagePattern":"cachebench: provider transport failed for %q: %w","errorType":"exception","errorClass":"ReplayRunError","httpStatus":null,"severity":"error","filePath":"cacheengine/cachebench/replay.go","lineNumber":695,"sourceCode":"\tevidence.HTTPStatus = response.StatusCode\n\tif len(response.Body) > 0 {\n\t\tevidence.ProviderEvidenceSHA256 = bodyDigest(response.Body)\n\t}\n\tif completed.Before(started) {\n\t\tevidence.CompletedAt = started.Format(time.RFC3339Nano)\n\t\tevidence.FailureCode = \"clock_regression\"\n\t\treturn ReplayResult{Evidence: evidence, ProviderResponse: append([]byte(nil), response.Body...)}, &ReplayRunError{\n\t\t\tRequestID: record.RequestID, FailureCode: evidence.FailureCode,\n\t\t\tErr: fmt.Errorf(\"cachebench: clock regressed while replaying %q\", record.RequestID),\n\t\t}\n\t}\n\tevidence.CompletedAt = completed.Format(time.RFC3339Nano)\n\tevidence.LatencyMilliseconds = completed.Sub(started).Milliseconds()\n\tif sendErr != nil {\n\t\tevidence.FailureCode = \"transport_error\"\n\t\treturn ReplayResult{Evidence: evidence, ProviderResponse: append([]byte(nil), response.Body...)}, &ReplayRunError{\n\t\t\tRequestID: record.RequestID, FailureCode: evidence.FailureCode,\n\t\t\tErr: fmt.Errorf(\"cachebench: provider transport failed for %q: %w\", record.RequestID, sendErr),\n\t\t}\n\t}\n\tif !validProviderRequestID(response.ProviderRequestID) {\n\t\tevidence.FailureCode = \"provider_response_invalid\"\n\t\treturn ReplayResult{Evidence: evidence, ProviderResponse: append([]byte(nil), response.Body...)}, &ReplayRunError{\n\t\t\tRequestID: record.RequestID, FailureCode: evidence.FailureCode,\n\t\t\tErr: fmt.Errorf(\"cachebench: provider returned invalid request identity for %q\", record.RequestID),\n\t\t}\n\t}\n\tevidence.ProviderRequestID = response.ProviderRequestID\n\tif response.StatusCode < 200 || response.StatusCode >= 300 {\n\t\tevidence.FailureCode = \"provider_http_status\"\n\t\treturn ReplayResult{Evidence: evidence, ProviderResponse: append([]byte(nil), response.Body...)}, &ReplayRunError{\n\t\t\tRequestID: record.RequestID, FailureCode: evidence.FailureCode,\n\t\t\tErr: fmt.Errorf(\"cachebench: provider returned HTTP %d for %q\", response.StatusCode, record.RequestID),\n\t\t}\n\t}\n\tusage, ok := cacheengine.ExtractProviderUsage(record.Provider, response.Body)","sourceCodeStart":677,"sourceCodeEnd":713,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/cacheengine/cachebench/replay.go#L677-L713","documentation":"Transport.Send returned a non-nil error while delivering the optimized request. The runner still records HTTP status and response body digest into evidence, then fails the request with FailureCode transport_error wrapping the transport error.","triggerScenarios":"Network failures to the provider endpoint (DNS, refused connection, TLS), context cancellation during send, proxy misconfiguration, or an overloaded provider closing connections. Any error from the injected Transport implementation lands here.","commonSituations":"Replaying against a provider API from a sandbox without egress; expired API credentials causing the transport's own error; corporate proxy required but not configured; context deadline hit during a slow streaming response.","solutions":["Unwrap and inspect the underlying error (%w) — it distinguishes DNS/TLS/auth/deadline causes.","Verify network egress, proxy settings, and credentials for the endpoint in the trace record.","Retry the replay: transient network errors are the most common cause, and replay is idempotent from the harness side.","If context.DeadlineExceeded, raise the per-run or transport timeout."],"exampleFix":"// before\nerr := runner.Run(ctx, records, emit) // fails: dial tcp: i/o timeout\n\n// after\n// fix egress/proxy, e.g.\ntransport := cachebench.NewHTTPTransport(cachebench.HTTPTransportConfig{Proxy: os.Getenv(\"HTTPS_PROXY\"), Timeout: 120 * time.Second})\nerr := runner.Run(ctx, records, emit)","handlingStrategy":"retry","validationCode":"// probe endpoint reachability before the run\nif err := transport.HealthCheck(ctx, endpoint); err != nil {\n    return fmt.Errorf(\"transport not ready: %w\", err)\n}","typeGuard":"func isTransportError(err error) bool {\n    var rre *cachebench.ReplayRunError\n    return errors.As(err, &rre) && rre.FailureCode == \"transport_error\"\n}","tryCatchPattern":"if err := runner.Run(ctx, records, emit); err != nil {\n    if isTransportError(err) {\n        cause := errors.Unwrap(err)\n        if isTransient(cause) { // net errors, TLS reset, 429-bearing transport errors\n            // fix network/credentials if not transient; otherwise re-run the replay\n        }\n    }\n    return err\n}","preventionTips":["Verify egress, proxy, DNS, and credentials with a single-request probe before replaying.","Set transport timeouts above worst-case provider latency.","Design replays to be re-runnable so transient network failures cost one retry."],"tags":["cachebench","network","transport","replay"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}