{"record":{"id":"ba84fe3b46c9dd39","repo":"chenhg5/cc-connect","slug":"download-exceeds-max-bytes-d-d","errorCode":null,"errorMessage":"download exceeds --max-bytes: %d > %d","messagePattern":"download exceeds --max-bytes: (.+?) > (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cc-connect/tuitui.go","lineNumber":190,"sourceCode":"func downloadTuiTuiURL(ctx context.Context, rawURL string, maxBytes int64) ([]byte, string, string, error) {\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, rawURL, nil)\n\tif err != nil {\n\t\treturn nil, \"\", \"\", err\n\t}\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\treturn nil, \"\", \"\", err\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\treturn nil, \"\", \"\", fmt.Errorf(\"HTTP %d\", resp.StatusCode)\n\t}\n\tlimit := maxBytes\n\tif limit <= 0 {\n\t\tlimit = 25 << 20\n\t}\n\tif resp.ContentLength > limit {\n\t\treturn nil, \"\", \"\", fmt.Errorf(\"download exceeds --max-bytes: %d > %d\", resp.ContentLength, limit)\n\t}\n\tdata, err := io.ReadAll(io.LimitReader(resp.Body, limit+1))\n\tif err != nil {\n\t\treturn nil, \"\", \"\", err\n\t}\n\tif int64(len(data)) > limit {\n\t\treturn nil, \"\", \"\", fmt.Errorf(\"download exceeds --max-bytes: %d > %d\", len(data), limit)\n\t}\n\tmimeType := resp.Header.Get(\"Content-Type\")\n\tif mimeType == \"\" || mimeType == \"application/octet-stream\" {\n\t\tmimeType = http.DetectContentType(data)\n\t}\n\treturn data, mimeType, filenameFromTuiTuiResponse(rawURL, resp.Header.Get(\"Content-Disposition\")), nil\n}\n\nfunc filenameFromTuiTuiResponse(rawURL, contentDisposition string) string {\n\tif contentDisposition != \"\" {\n\t\t_, params, err := mime.ParseMediaType(contentDisposition)","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/cmd/cc-connect/tuitui.go#L172-L208","documentation":"When the HTTP response declares a Content-Length larger than the configured --max-bytes limit, downloadTuiTuiURL aborts before reading the body. Default limit is 25 MiB when maxBytes is unset (<=0). This protects memory by refusing oversized downloads upfront.","triggerScenarios":"resp.ContentLength > limit, i.e. server sends Content-Length header exceeding --max-bytes (or the 25MiB default) in runTuiTuiDownload.","commonSituations":"Downloading a large binary/attachment while forgetting to raise --max-bytes; default 25MiB limit hit on legitimate big files.","solutions":["Raise --max-bytes (e.g. --max-bytes 104857600 for 100MB)","If the file is genuinely unwanted-large, pick a smaller asset URL","Pass 0 or negative only intentionally to fall back to the 25MiB default"],"exampleFix":"// before\ncc-connect tuitui download --url https://example.com/big.bin\n// after\ncc-connect tuitui download --url https://example.com/big.bin --max-bytes 104857600","handlingStrategy":"validation","validationCode":"resp, err := http.Head(url)\nif err == nil && resp.ContentLength > maxBytes {\n\treturn fmt.Errorf(\"file is %d bytes; raise --max-bytes\", resp.ContentLength)\n}","typeGuard":null,"tryCatchPattern":"if _, _, _, err := downloadTuiTuiURL(ctx, url, maxBytes); err != nil {\n\tif strings.Contains(err.Error(), \"exceeds --max-bytes\") {\n\t\t// retry with a larger limit or skip\n\t}\n}","preventionTips":["Check Content-Length via HEAD before downloading","Set --max-bytes deliberately rather than relying on the 25MiB default","Stream to disk instead of memory for very large files"],"tags":["http","download","limit","cli"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}