larksuite/cli · error

download transport received a nil request

Error message

download transport received a nil request

What it means

proxyAwareDownloadTransport.RoundTrip guards against being invoked with a nil *http.Request or a request with a nil URL (internal/validate/url.go:202) and returns this error instead of panicking. This is an internal invariant: the http.Client stack should never dispatch a nil request to a RoundTripper, so hitting this indicates the transport is being used outside the normal client flow or a caller constructed/modified requests incorrectly.

Source

Thrown at internal/validate/url.go:202

	}
	return t.base.RoundTrip(req)
}

type selectedDownloadProxyKey struct{}

type proxyAwareDownloadTransport struct {
	selectProxy func(*http.Request) (*url.URL, error)
	direct      http.RoundTripper
	proxied     *http.Transport
	lookupIP    downloadLookupIPFunc

	mu                 sync.Mutex
	proxiedByTLSServer map[string]*http.Transport
}

func (t *proxyAwareDownloadTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	if req == nil || req.URL == nil {
		return nil, fmt.Errorf("download transport received a nil request")
	}
	proxyURL, err := t.selectProxy(req)
	if err != nil {
		return nil, err
	}
	if proxyURL == nil {
		return t.direct.RoundTrip(req)
	}

	targetIPs, err := resolveDownloadHost(req.Context(), req.URL.Hostname(), t.lookupIP)
	if err != nil {
		return nil, errs.NewSecurityPolicyError(
			errs.SubtypeAccessDenied,
			"blocked download target: %v",
			err,
		).WithCause(err)
	}
	if strings.EqualFold(req.URL.Scheme, "http") && net.ParseIP(req.URL.Hostname()) == nil {

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Always issue requests through the http.Client returned by NewDownloadHTTPClient rather than calling RoundTrip directly.
  2. When calling RoundTrip manually, ensure the *http.Request is non-nil and constructed with http.NewRequest (which always sets URL).
  3. Audit any wrapping RoundTripper so it forwards the original request and never passes nil or strips the URL.

Example fix

// before
resp, err := transport.RoundTrip(nil)
// after
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://example.com/file", nil)
resp, err := client.Do(req)
Defensive patterns

Strategy: type-guard

Validate before calling

if req == nil || req.URL == nil {
    return fmt.Errorf("request and URL must be set before invoking transport")
}

Type guard

func isUsableHTTPRequest(req *http.Request) bool {
    return req != nil && req.URL != nil
}

Try / catch

if !isUsableHTTPRequest(req) {
    return fmt.Errorf("cannot send nil request to download transport")
}
resp, err := transport.RoundTrip(req)
if err != nil {
    if strings.Contains(err.Error(), "nil request") {
        return fmt.Errorf("transport misuse: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling RoundTrip directly on a proxyAwareDownloadTransport (obtained via NewDownloadHTTPClient's transport chain) with a nil request or a request whose URL field is nil; misuse in tests or custom client code that bypasses http.Client.

Common situations: Custom middleware or test harnesses invoking transport.RoundTrip(nil); wrapping the download transport in another RoundTripper that drops or fails to populate the request; programming errors when hand-assembling *http.Request without a URL.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/cd6cd82e30e98167. Report an issue: GitHub.