{"record":{"id":"b1c0d75828d7155a","repo":"router-for-me/CLIProxyAPI","slug":"response-exceeds-maximum-allowed-size-of-d-bytes-b1c0d7","errorCode":null,"errorMessage":"response exceeds maximum allowed size of %d bytes","messagePattern":"response exceeds maximum allowed size of (.+?) bytes","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/github.go","lineNumber":284,"sourceCode":"\t\t}\n\t}()\n\tif resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {\n\t\tif authenticated {\n\t\t\treturn nil, fmt.Errorf(\"unexpected status %d\", resp.StatusCode)\n\t\t}\n\t\tbody, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))\n\t\treturn nil, fmt.Errorf(\"unexpected status %d: %s\", resp.StatusCode, strings.TrimSpace(string(body)))\n\t}\n\treader := io.Reader(resp.Body)\n\tif maxSize > 0 {\n\t\treader = io.LimitReader(resp.Body, maxSize+1)\n\t}\n\tdata, errRead := io.ReadAll(reader)\n\tif errRead != nil {\n\t\treturn nil, fmt.Errorf(\"read response: %w\", errRead)\n\t}\n\tif maxSize > 0 && int64(len(data)) > maxSize {\n\t\treturn nil, fmt.Errorf(\"response exceeds maximum allowed size of %d bytes\", maxSize)\n\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}","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/github.go#L266-L302","documentation":"A download from the plugin store GitHub API returned a body larger than the caller's maxSize limit (enforced via io.LimitReader with maxSize+1). The client downloads release assets and API payloads through a bounded reader; when len(data) exceeds maxSize the fetch is rejected outright. This protects against unexpectedly huge responses such as a mis-published asset or a proxy/HTML error page masquerading as content.","triggerScenarios":"Calling the GitHub helper's fetch path (used by FetchReleaseByTag / DownloadAsset) where the server returns more bytes than the configured maxSize > 0. Common with large plugin archives downloaded through the metadata-fetch code path instead of the asset-download path, or when a redirect/HTML page is returned.","commonSituations":"Downloading a plugin release archive whose size exceeds the metadata size cap; a CDN or captive portal returning an oversized HTML page; maxSize defaults tuned for JSON being used for binary artifacts.","solutions":["If downloading a release archive, use the asset download path (DownloadAsset) rather than the metadata fetch that enforces the smaller cap","Raise the maxSize argument passed to the fetch helper to exceed the real asset size (check the release's asset size field)","Check the request URL — an HTML error page means auth/rate-limit trouble, not a size problem; fix the underlying HTTP status","Verify the correct release tag/asset is being fetched (wrong asset name can hit an oversized page)"],"exampleFix":"// before\ndata, err := client.fetch(ctx, metadataURL, 1<<20) // metadata cap used for archive\n\n// after\nasset, checksum, err := pluginstore.SelectReleaseAssets(release, id, version, runtime.GOOS, runtime.GOARCH)\n// ... archiveData, err := client.DownloadAsset(ctx, asset)","handlingStrategy":"validation","validationCode":"// Before fetching, confirm expected size fits the cap you pass.\nif expected > 0 && expected > maxSize {\n    return fmt.Errorf(\"asset %s is %d bytes, exceeds cap %d\", name, expected, maxSize)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"response exceeds maximum allowed size\") {\n    // re-fetch via the asset download path with an adequate/no cap, or reject the asset\n}","preventionTips":["Use the metadata fetch path only for JSON and the asset path for binaries","Pass a maxSize comfortably larger than the largest legitimate payload","Treat oversized 'JSON' responses as a signal the URL is wrong (HTML error page)"],"tags":["network","download","size-limit","github-api","go"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}