wtfutil/wtf · error
invalid base URL: %w
Error message
invalid base URL: %w
What it means
devto Client.FetchArticles starts by parsing c.baseURL with url.Parse; if that fails the error is wrapped as 'invalid base URL'. This only happens when the configured base URL is not a valid URL string, which normally indicates bad construction of the Client rather than a network problem.
Source
Thrown at modules/devto/client.go:44
}
// NewClient creates a Client. Pass nil for httpClient to use http.DefaultClient.
// baseURL overrides the API endpoint (useful for testing); pass "" for the default.
func NewClient(httpClient *http.Client, baseURL string) *Client {
if httpClient == nil {
httpClient = http.DefaultClient
}
if baseURL == "" {
baseURL = defaultBaseURL
}
return &Client{httpClient: httpClient, baseURL: baseURL}
}
// FetchArticles retrieves articles matching the given filters.
func (c *Client) FetchArticles(ctx context.Context, tag, username, state string, perPage int) ([]Article, error) {
u, err := url.Parse(c.baseURL)
if err != nil {
return nil, fmt.Errorf("invalid base URL: %w", err)
}
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)View on GitHub (pinned to bb838c1ccb)
Solutions
- Use the default DEV.to base URL (https://dev.to/api) unless overriding intentionally
- Validate the custom base URL with url.Parse before constructing the Client
- Print/log c.baseURL to spot stray characters or empty scheme
Example fix
// before
client := NewClient("http://dev.to/api/{bad url}")
// after
u, err := url.Parse("https://dev.to/api")
if err != nil {
return err
}
client := NewClient(u.String()) Defensive patterns
Strategy: validation
Validate before calling
func validateBaseURL(raw string) error {
if raw == "" {
return errors.New("base URL is empty")
}
if _, err := url.Parse(raw); err != nil {
return fmt.Errorf("invalid base URL %q: %w", raw, err)
}
return nil
}
if err := validateBaseURL(baseURL); err != nil { return err } Try / catch
articles, err := client.FetchArticles(ctx, tag, user, state, perPage)
if err != nil {
if strings.HasPrefix(err.Error(), "invalid base URL") {
return fmt.Errorf("misconfigured devto client: %w", err)
}
return err
} Prevention
- Default to https://dev.to/api; only override in tests
- Validate any override URL with url.Parse before NewClient
- Never build URLs by raw string concatenation of config values
When it happens
Trigger: url.Parse(c.baseURL) errors — e.g. baseURL contains control characters or an unparsable scheme — when NewClient was given a malformed override URL instead of the default DEV.to endpoint.
Common situations: Passing an empty-with-garbage or typo'd base URL override in tests or custom configuration; concatenating config values into the URL producing invalid characters.
Related errors
- creating request: %w
- failed to initialize Azure session: %w
- executing request: %w
- could not create client: %w
- unable to get the league id for provided league '%s'
AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03).
Data as JSON: /api/errors/e7148c266a3e2935.
Report an issue: GitHub.