PuerkitoBio/goquery · error

Response is nil

Error message

Response is nil

What it means

NewDocumentFromResponse returns this error when the *http.Response passed to it is nil. The function needs a live response whose body it will parse into a Document, so a nil response is rejected immediately before any parsing happens. It is a simple defensive guard added to prevent a nil-pointer panic inside the function.

Source

Thrown at type.go:66

// as html. It does not check if the reader is also an io.Closer, the
// provided reader is never closed by this call. It is the responsibility
// of the caller to close it if required.
func NewDocumentFromReader(r io.Reader) (*Document, error) {
	root, e := html.Parse(r)
	if e != nil {
		return nil, e
	}
	return newDocument(root, nil), nil
}

// NewDocumentFromResponse is another Document constructor that takes an http response as argument.
// It loads the specified response's document, parses it, and stores the root Document
// node, ready to be manipulated. The response's body is closed on return.
//
// Deprecated: Use goquery.NewDocumentFromReader with the response's body.
func NewDocumentFromResponse(res *http.Response) (*Document, error) {
	if res == nil {
		return nil, errors.New("Response is nil")
	}
	defer res.Body.Close()
	if res.Request == nil {
		return nil, errors.New("Response.Request is nil")
	}

	// Parse the HTML into nodes
	root, e := html.Parse(res.Body)
	if e != nil {
		return nil, e
	}

	// Create and fill the document
	return newDocument(root, res.Request.URL), nil
}

// CloneDocument creates a deep-clone of a document.
func CloneDocument(doc *Document) *Document {

View on GitHub (pinned to 738783cbc3)

Solutions

  1. Check that the *http.Response is non-nil before calling NewDocumentFromResponse, e.g. if res == nil { return nil }.
  2. Inspect the error return of the HTTP call that produced the response; when err != nil the response is nil.
  3. Migrate to goquery.NewDocumentFromReader(res.Body) after verifying res and res.Body yourself, as the deprecation notice recommends.

Example fix

// before
res, _ := http.Get(url)
doc, err := goquery.NewDocument(res) // panics-path: NewDocumentFromResponse(nil)

// after
res, err := http.Get(url)
if err != nil {
	return err
}
doc, err := goquery.NewDocumentFromResponse(res)
Defensive patterns

Strategy: validation

Validate before calling

if res == nil {
	// caller-side guard before goquery
	return errors.New("no response to parse")
}
doc, err := goquery.NewDocumentFromResponse(res)

Type guard

func hasResponse(res *http.Response) bool { return res != nil }

Prevention

When it happens

Trigger: Calling goquery.NewDocumentFromResponse(nil) directly, or calling goquery.NewDocument (the deprecated convenience wrapper) with a nil *http.Response, typically when an HTTP client helper returned (nil, err) and the caller only checked one of the two return values.

Common situations: Ignoring the error from http.Client.Do / http.Get and passing the nil response onward; a helper function that returns *http.Response without propagating errors; old code written before NewDocumentFromReader existed that refactored to return nil on failure paths.

Related errors


AI-assisted analysis of PuerkitoBio/goquery@738783cbc3 (2026-09-06). Data as JSON: /api/errors/bc264ccb8f842f6c. Report an issue: GitHub.