wtfutil/wtf · error

creating request: %w

Error message

creating request: %w

What it means

FetchArticles wraps errors from http.NewRequestWithContext as 'creating request'. This means the request object could not be built — almost always because the composed URL string is malformed (bad method, unparsable URL) — and occurs before any network I/O.

Source

Thrown at modules/devto/client.go:64

	q := u.Query()
	if tag != "" {
		q.Set("tag", tag)
	}
	if username != "" {
		q.Set("username", username)
	}
	if state != "" {
		q.Set("state", state)
	}
	if perPage > 0 {
		q.Set("per_page", fmt.Sprintf("%d", perPage))
	}
	u.RawQuery = q.Encode()

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
	if err != nil {
		return nil, fmt.Errorf("creating request: %w", err)
	}

	resp, err := c.httpClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("executing request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("unexpected status %d from DEV.to API", resp.StatusCode)
	}

	var articles []Article
	if err := json.NewDecoder(resp.Body).Decode(&articles); err != nil {
		return nil, fmt.Errorf("decoding response: %w", err)
	}

	return articles, nil

View on GitHub (pinned to bb838c1ccb)

Solutions

  1. Sanitize/validate filter inputs (tag, username, state) before calling FetchArticles
  2. Log u.String() just before building the request to inspect the final URL
  3. Ensure the context passed in is not already canceled and the URL parses cleanly

Example fix

// before
articles, err := client.FetchArticles(ctx, "go lang", "", "", 10) // space in tag → bad URL
// after
articles, err := client.FetchArticles(ctx, "go-lang", "", "", 10)
// or url.QueryEscape(userTag) before interpolating
Defensive patterns

Strategy: validation

Validate before calling

func sanitizeFilter(s string) string {
    return url.QueryEscape(strings.TrimSpace(s))
}
tag, user, state := sanitizeFilter(tag), sanitizeFilter(user), sanitizeFilter(state)
articles, err := client.FetchArticles(ctx, tag, user, state, perPage)

Try / catch

articles, err := client.FetchArticles(ctx, tag, user, state, perPage)
if err != nil {
    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
        return nil, err // caller-owned context issue
    }
    return nil, fmt.Errorf("devto: %w", err)
}

Prevention

When it happens

Trigger: http.NewRequestWithContext returns an error when building the GET request to u.String() — typically because query encoding or baseURL parsing produced an invalid URL (e.g. invalid characters in tag/username/state filter values).

Common situations: User-supplied filter values containing spaces or illegal URL characters interpolated into the URL; context already canceled before request creation; misconfigured baseURL leaking into the final URL.

Related errors


AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03). Data as JSON: /api/errors/02d22e85c2b743d3. Report an issue: GitHub.