{"record":{"id":"dbd3dd6d9d0875ac","repo":"router-for-me/CLIProxyAPI","slug":"request-s-failed-w","errorCode":null,"errorMessage":"request %s failed: %w","messagePattern":"request (.+?) failed: %w","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/github.go","lineNumber":303,"sourceCode":"\t}\n\treturn data, nil\n}\n\nfunc pluginStoreRequestError(requestURL string, err error) error {\n\tparsed, errParse := url.Parse(strings.TrimSpace(requestURL))\n\tsafeURL := \"plugin store url\"\n\tif errParse == nil && parsed.Scheme != \"\" && parsed.Host != \"\" {\n\t\tparsed.User = nil\n\t\tparsed.RawQuery = \"\"\n\t\tparsed.ForceQuery = false\n\t\tparsed.Fragment = \"\"\n\t\tsafeURL = parsed.String()\n\t}\n\tvar urlError *url.Error\n\tif errors.As(err, &urlError) && urlError.Err != nil {\n\t\terr = urlError.Err\n\t}\n\treturn fmt.Errorf(\"request %s failed: %w\", safeURL, err)\n}\n\nfunc SelectReleaseAssets(release Release, id, version, goos, goarch string) (ReleaseAsset, ReleaseAsset, error) {\n\tarchiveName := ArchiveName(id, version, goos, goarch)\n\tvar archiveAsset ReleaseAsset\n\tvar checksumAsset ReleaseAsset\n\tfor _, asset := range release.Assets {\n\t\tswitch strings.TrimSpace(asset.Name) {\n\t\tcase archiveName:\n\t\t\tarchiveAsset = asset\n\t\tcase \"checksums.txt\":\n\t\t\tchecksumAsset = asset\n\t\t}\n\t}\n\tif strings.TrimSpace(archiveAsset.Name) == \"\" {\n\t\treturn ReleaseAsset{}, ReleaseAsset{}, fmt.Errorf(\"release asset %s not found\", archiveName)\n\t}\n\tif strings.TrimSpace(checksumAsset.Name) == \"\" {","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/github.go#L285-L321","documentation":"The HTTP request to the plugin store / GitHub release endpoint failed at the transport level. The helper sanitizes the URL (strips user info, query, fragment) and unwraps *url.Error before wrapping, so the message shows a safe URL plus the underlying error (DNS failure, timeout, TLS, connection refused). It is the generic network-failure envelope for all plugin store HTTP calls.","triggerScenarios":"Any plugin store HTTP request (release fetch, asset download) when the underlying http.Client request returns an error: no network, DNS resolution failure, proxy misconfiguration, TLS handshake failure, or context cancellation.","commonSituations":"Running in an offline/CI sandbox without egress to github.com; corporate MITM proxy with an untrusted CA; mistyped plugin store base URL; context cancelled mid-download.","solutions":["Verify network egress to the host named in the error (curl the sanitized URL shown in the message)","Fix proxy/CA configuration (set HTTPS_PROXY or add the corporate CA to the trust store)","Retry transient failures — network errors are often intermittent; the store client treats them as retryable","If the URL looks wrong, correct the plugin source/repo configuration in the manifest"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-flight reachability check before install flows.\nif _, errPing := http.Head(storeURL); errPing != nil {\n    return fmt.Errorf(\"plugin store unreachable, check network: %w\", errPing)\n}","typeGuard":null,"tryCatchPattern":"var urlErr *url.Error\nif errors.As(err, &urlErr) {\n    // transport-level failure: safe to retry with backoff; abort on context.Canceled\n}","preventionTips":["Ensure egress to the plugin store host is allowed in CI/sandbox","Configure proxy env vars and trust CAs before installs","Wrap installs in a retry-with-backoff helper for transient DNS/TLS failures"],"tags":["network","http","dns","proxy","go"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}