router-for-me/CLIProxyAPI · warning
parse redirect base: %w
Error message
parse redirect base: %w
What it means
In pluginStoreRedirectURL the current (request) URL is parsed with url.Parse to serve as the base for resolving a relative Location. 'parse redirect base: %w' wraps that parse failure — the URL already being fetched could not be parsed as an absolute URL. It is a defensive check; normally the earlier request construction would have failed first.
Source
Thrown at internal/pluginstore/github.go:250
}
func pluginStoreRedirectStatus(status int) bool {
switch status {
case http.StatusMovedPermanently, http.StatusFound, http.StatusSeeOther, http.StatusTemporaryRedirect, http.StatusPermanentRedirect:
return true
default:
return false
}
}
func pluginStoreRedirectURL(resp *http.Response, requestURL string) (string, error) {
location := strings.TrimSpace(resp.Header.Get("Location"))
if location == "" {
return "", fmt.Errorf("redirect missing Location header")
}
base, errBase := url.Parse(requestURL)
if errBase != nil {
return "", fmt.Errorf("parse redirect base: %w", errBase)
}
next, errNext := base.Parse(location)
if errNext != nil {
return "", fmt.Errorf("parse redirect location: %w", errNext)
}
if next.Scheme == "" || next.Host == "" {
return "", fmt.Errorf("redirect location is not absolute")
}
return next.String(), nil
}
func readPluginStoreResponse(resp *http.Response, maxSize int64, authenticated bool) ([]byte, error) {
defer func() {
if errClose := resp.Body.Close(); errClose != nil {
log.WithError(errClose).Debug("failed to close plugin store response body")
}
}()
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {View on GitHub (pinned to 78f0c4079e)
Solutions
- Validate/normalize the URL (url.Parse + check Scheme/Host) before handing it to the plugin store client.
- url.PathEscape any dynamic path components when building URLs.
Example fix
// before
u := fmt.Sprintf("https://host/plugins/%s", name) // name='my plugin' (space)
// after
u := fmt.Sprintf("https://host/plugins/%s", url.PathEscape(name)) Defensive patterns
Strategy: validation
Validate before calling
if _, err := url.Parse(rawURL); err != nil {
return fmt.Errorf("unparseable plugin url %q: %w", rawURL, err)
} Prevention
- Validate URLs once at the boundary (config load) instead of relying on inner defensive checks.
- Escape dynamic URL components.
When it happens
Trigger: url.Parse(requestURL) failing on the in-flight URL — control characters or a truly malformed URL that somehow passed request creation (e.g. a non-standard HTTPDoer accepting the request). Note url.Parse is lenient; failures here require control characters or similar.
Common situations: Custom HTTPDoer implementations or tests injecting odd URLs; URLs containing raw CR/LF introduced dynamically between request creation and redirect handling.
Related errors
- parse redirect location: %w
- redirect location is not absolute
- stopped after %d redirects
- create request: %w
- redirect missing Location header
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/660dd10166d6b0c4.
Report an issue: GitHub.