router-for-me/CLIProxyAPI · error
create request: %w
Error message
create request: %w
What it means
pluginStoreGetNoRedirect builds the http.Request for each hop of the manual redirect follower. 'create request: %w' wraps the error from http.NewRequestWithContext and indicates the request could not even be constructed — the URL string (or context) is invalid at the net/http level, before any network I/O.
Source
Thrown at internal/pluginstore/github.go:212
return c.HTTPClient
}
return http.DefaultClient
}
func (c Client) userAgent() string {
if strings.TrimSpace(c.UserAgent) != "" {
return strings.TrimSpace(c.UserAgent)
}
return userAgent
}
func pluginStoreGetNoRedirect(ctx context.Context, client HTTPDoer, requestURL string, headers http.Header) (*http.Response, error) {
if client == nil {
client = http.DefaultClient
}
req, errRequest := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil)
if errRequest != nil {
return nil, fmt.Errorf("create request: %w", errRequest)
}
req.Header = headers.Clone()
resp, errDo := pluginStoreNoRedirectClient(client).Do(req)
if errDo != nil {
return nil, pluginStoreRequestError(requestURL, errDo)
}
return resp, nil
}
func pluginStoreNoRedirectClient(client HTTPDoer) HTTPDoer {
httpClient, ok := client.(*http.Client)
if !ok {
return client
}
clone := *httpClient
clone.CheckRedirect = func(*http.Request, []*http.Request) error {
return http.ErrUseLastResponse
}View on GitHub (pinned to 78f0c4079e)
Solutions
- Log the exact URL being fetched when this error appears; it will contain the malformed component.
- url.PathEscape or properly join URL components when constructing release/asset URLs instead of raw fmt.Sprintf of user input.
- If a server emits malformed Location headers, pin the artifact URL to a well-behaved host.
Example fix
// before
u := fmt.Sprintf("https://host/%s", plugin.Name) // name with spaces -> create request error
// after
u := fmt.Sprintf("https://host/%s", url.PathEscape(plugin.Name)) Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(rawURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid plugin store url %q", rawURL)
} Prevention
- Always url.PathEscape dynamic path segments.
- Parse-and-validate URLs at config load time rather than at request time.
When it happens
Trigger: A request URL that fails parsing/validation in net/http: control characters, spaces, or a completely malformed URL reaching this function — most plausibly a Location header from a previous redirect that could not be normalized, or an empty/garbage URL passed into the getter.
Common situations: A redirect Location containing raw spaces or CR/LF (some misconfigured servers emit these); a caller-supplied base URL assembled by string concatenation with an unescaped component. Note pluginStoreRedirectURL already resolves and validates Location, so reaching this with a bad URL usually means the initial URL was broken.
Related errors
- parse redirect location: %w
- redirect location is not absolute
- invalid_request
- stopped after %d redirects
- redirect missing Location header
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/e710ace242d1cad0.
Report an issue: GitHub.