chenhg5/cc-connect · warning
unexpected redirect: %s
Error message
unexpected redirect: %s
What it means
fetchLatestStableRelease parses the redirect Location URL by splitting on "/tag/" and expects exactly two parts. This error means the Location header was present but its format didn't match the expected https://github.com/<owner>/<repo>/releases/tag/<tag> shape, so the tag cannot be extracted.
Source
Thrown at cmd/cc-connect/update.go:282
noRedirect := &http.Client{
Timeout: 15 * time.Second,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
resp2, err := noRedirect.Get(latestURL)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp2.Body.Close()
loc := resp2.Header.Get("Location")
if loc == "" {
return nil, fmt.Errorf("no release found")
}
parts := strings.Split(loc, "/tag/")
if len(parts) != 2 {
return nil, fmt.Errorf("unexpected redirect: %s", loc)
}
return &githubRelease{TagName: parts[1], HTMLURL: loc}, nil
}
func binaryAssetName(tag string) string {
goos := runtime.GOOS
goarch := runtime.GOARCH
name := fmt.Sprintf("cc-connect-%s-%s-%s", tag, goos, goarch)
if goos == "windows" {
name += ".exe"
}
return name
}
func archiveAssetName(tag string) string {
goos := runtime.GOOS
goarch := runtime.GOARCH
base := fmt.Sprintf("cc-connect-%s-%s-%s", tag, goos, goarch)View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the actual Location value embedded in the message to see what GitHub returned
- Bypass any SSO/proxy that rewrites redirects to github.com
- Parse the tag with net/url path parsing instead of naive string splitting to tolerate URL variations
- Fall back to the JSON /releases endpoint, whose tag_name field is stable
Example fix
// before
parts := strings.Split(loc, "/tag/")
if len(parts) != 2 {
return nil, fmt.Errorf("unexpected redirect: %s", loc)
}
// after
u, err := url.Parse(loc)
if err != nil {
return nil, fmt.Errorf("unexpected redirect: %s", loc)
}
segs := strings.Split(strings.TrimRight(u.Path, "/"), "/")
if len(segs) < 2 || segs[len(segs)-2] != "tag" {
return nil, fmt.Errorf("unexpected redirect: %s", loc)
}
tag := segs[len(segs)-1] Defensive patterns
Strategy: type-guard
Validate before calling
// sanity-check the Location URL shape before trusting it:
loc := resp.Header.Get("Location")
u, err := url.Parse(loc)
if err != nil || u.Host != "github.com" || !strings.Contains(u.Path, "/releases/tag/") {
return errors.New("redirect does not look like a release URL: " + loc)
} Type guard
// Go: narrowing helper for a valid release-redirect URL
func isReleaseRedirect(loc string) (tag string, ok bool) {
u, err := url.Parse(loc)
if err != nil || u.Host != "github.com" { return "", false }
parts := strings.Split(strings.Trim(u.Path, "/"), "/")
if len(parts) < 5 || parts[len(parts)-2] != "tag" { return "", false }
return parts[len(parts)-1], true
} Try / catch
// Go: validate the parsed tag before proceeding
tag, ok := isReleaseRedirect(loc)
if !ok {
return nil, fmt.Errorf("unexpected redirect: %s", loc) // log loc verbatim for triage
} Prevention
- Parse URLs with net/url instead of fragile string splitting
- Expect SSO/IDP redirects in corporate environments and bypass them for github.com
- Log the full Location header whenever parsing fails
- Add an integration test that asserts the current GitHub releases URL layout
When it happens
Trigger: strings.Split(loc, "/tag/") returns != 2 parts: Location points somewhere unexpected — a login/SSO redirect, an error page, a proxy URL, or a changed releases URL layout.
Common situations: An SSO/identity provider redirect intercepting the request; a misconfigured internal proxy rewriting Location; repo moved/renamed causing a redirect chain to a different URL format; future GitHub URL scheme change.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/c45bd26b41138172.
Report an issue: GitHub.