{"record":{"id":"8a4ffcdf7995db89","repo":"PuerkitoBio/goquery","slug":"response-request-is-nil","errorCode":null,"errorMessage":"Response.Request is nil","messagePattern":"Response\\.Request is nil","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"type.go","lineNumber":70,"sourceCode":"\troot, e := html.Parse(r)\n\tif e != nil {\n\t\treturn nil, e\n\t}\n\treturn newDocument(root, nil), nil\n}\n\n// NewDocumentFromResponse is another Document constructor that takes an http response as argument.\n// It loads the specified response's document, parses it, and stores the root Document\n// node, ready to be manipulated. The response's body is closed on return.\n//\n// Deprecated: Use goquery.NewDocumentFromReader with the response's body.\nfunc NewDocumentFromResponse(res *http.Response) (*Document, error) {\n\tif res == nil {\n\t\treturn nil, errors.New(\"Response is nil\")\n\t}\n\tdefer res.Body.Close()\n\tif res.Request == nil {\n\t\treturn nil, errors.New(\"Response.Request is nil\")\n\t}\n\n\t// Parse the HTML into nodes\n\troot, e := html.Parse(res.Body)\n\tif e != nil {\n\t\treturn nil, e\n\t}\n\n\t// Create and fill the document\n\treturn newDocument(root, res.Request.URL), nil\n}\n\n// CloneDocument creates a deep-clone of a document.\nfunc CloneDocument(doc *Document) *Document {\n\treturn newDocument(cloneNode(doc.rootNode), doc.Url)\n}\n\n// Private constructor, make sure all fields are correctly filled.","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/PuerkitoBio/goquery/blob/738783cbc3c6244dea65b66306dae4fd0f84e7e3/type.go#L52-L88","documentation":"NewDocumentFromResponse requires res.Request (the request that generated the response) to be non-nil, because it uses res.Request.URL to resolve relative links when building the Document. If the response was constructed manually (e.g. httptest.ResponseRecorder or &http.Response{} literal) without setting Request, this error is returned.","triggerScenarios":"Passing an *http.Response that was hand-constructed or produced by httptest.NewRecorder().Result() without assigning res.Request; responses from clients that do not populate Request.","commonSituations":"Unit tests building fake responses with httptest where only Body/StatusCode were set; deserialized responses from caches or mocks; constructing a response from a saved payload and forgetting Request.URL.","solutions":["Assign a request to the response before parsing: res.Request = &http.Request{Method: \"GET\", URL: parsedURL}.","In tests, set httptest.NewRequest(...) and recorder.Result().Request = req, or use http.Client against httptest.Server so Request is populated.","Use goquery.NewDocumentFromReader(res.Body) if you do not need URL-based relative-link resolution."],"exampleFix":"// before\nrec := httptest.NewRecorder()\nrec.WriteString(\"<html></html>\")\ndoc, err := goquery.NewDocumentFromResponse(rec.Result()) // Request is nil\n\n// after\nreq := httptest.NewRequest(\"GET\", \"http://example.com/\", nil)\nrec := httptest.NewRecorder()\nrec.WriteString(\"<html></html>\")\nres := rec.Result()\nres.Request = req\ndoc, err := goquery.NewDocumentFromResponse(res)","handlingStrategy":"validation","validationCode":"if res == nil || res.Request == nil || res.Request.URL == nil {\n\treturn errors.New(\"response lacks Request/URL context\")\n}\ndoc, err := goquery.NewDocumentFromResponse(res)","typeGuard":"func hasRequestContext(res *http.Response) bool {\n\treturn res != nil && res.Request != nil && res.Request.URL != nil\n}","tryCatchPattern":null,"preventionTips":["In tests using httptest.ResponseRecorder, always attach res.Request = httptest.NewRequest(...).","Never hand-build http.Response literals without setting Request.URL.","Mock at the http.RoundTripper/httptest.Server level so responses carry their originating request."],"tags":["go","goquery","http-response","testing"],"backgroundTag":"missing-required-argument","analyzedSha":"738783cbc3c6244dea65b66306dae4fd0f84e7e3","analyzedAt":"2026-09-06T07:49:12.071Z","contentChangedAt":"2026-09-06T07:49:12.071Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}