{"record":{"id":"b2dd135b8e7032fc","repo":"JuliusBrussee/caveman","slug":"rewriter-s-nil-response","errorCode":null,"errorMessage":"rewriter: %s: nil response","messagePattern":"rewriter: (.+?): nil response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rewriter/provider.go","lineNumber":193,"sourceCode":"\t\treturn nil, fmt.Errorf(\"rewriter: encode request: %w\", err)\n\t}\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(encoded))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rewriter: build request: %w\", err)\n\t}\n\treq.Header.Set(\"content-type\", \"application/json\")\n\tfor key, value := range headers {\n\t\treq.Header.Set(key, value)\n\t}\n\n\tresp, err := c.doer(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rewriter: %s: %w\", endpoint, err)\n\t}\n\t// An injected doer is caller code; a nil response or body must surface as an\n\t// error rather than a panic inside the proxy hot path.\n\tif resp == nil {\n\t\treturn nil, fmt.Errorf(\"rewriter: %s: nil response\", endpoint)\n\t}\n\tif resp.Body == nil {\n\t\tresp.Body = http.NoBody\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode < 200 || resp.StatusCode > 299 {\n\t\tdetail, _ := io.ReadAll(io.LimitReader(resp.Body, maxErrorBody))\n\t\treturn nil, fmt.Errorf(\"rewriter: %s: status %d: %s\", endpoint, resp.StatusCode, strings.TrimSpace(string(detail)))\n\t}\n\traw, err := io.ReadAll(io.LimitReader(resp.Body, maxProviderResponseBody+1))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"rewriter: read response: %w\", err)\n\t}\n\tif len(raw) > maxProviderResponseBody {\n\t\treturn nil, fmt.Errorf(\"rewriter: response exceeds %d bytes\", maxProviderResponseBody)\n\t}\n\treturn raw, nil","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/766dce6b1394ebb56a3090748d5a0240a5aefb36/rewriter/provider.go#L175-L211","documentation":"The rewriter Client's injected doer (caller-supplied http.RoundTripper) returned a nil *http.Response with a nil error, which is a contract violation of http.Client/RoundTripper. The explicit check converts what would be a panic in the proxy hot path into an error.","triggerScenarios":"Thrown at rewriter/provider.go:193 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Fix the injected doer so it never returns (nil, nil)","Return an error from the custom RoundTripper on failure paths"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"766dce6b1394ebb56a3090748d5a0240a5aefb36","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}