{"record":{"id":"c7f5feb0db3e57d2","repo":"schollz/croc","slug":"could-not-parse-given-upload-limit","errorCode":null,"errorMessage":"Could not parse given Upload Limit","messagePattern":"Could not parse given Upload Limit","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/croc/croc.go","lineNumber":275,"sourceCode":"\n\tcodeComponents, err := codephrase.Parse(c.Options.SharedSecret)\n\tif err != nil {\n\t\treturn\n\t}\n\tc.Options.RoomName = codeComponents.RoomName\n\tc.pakePassphrase = codeComponents.PAKEPassphrase\n\tc.baseRoomName = c.Options.RoomName\n\tc.reconnectVersion = ReconnectVersion\n\n\tc.conn = make([]*comm.Comm, 16)\n\n\t// initialize throttler\n\tif len(c.Options.ThrottleUpload) > 1 && c.Options.IsSender {\n\t\tupload := c.Options.ThrottleUpload[:len(c.Options.ThrottleUpload)-1]\n\t\tvar uploadLimit int64\n\t\tuploadLimit, err = strconv.ParseInt(upload, 10, 64)\n\t\tif err != nil {\n\t\t\tpanic(\"Could not parse given Upload Limit\")\n\t\t}\n\t\tminBurstSize := models.TCP_BUFFER_SIZE\n\t\tvar rt rate.Limit\n\t\tswitch unit := string(c.Options.ThrottleUpload[len(c.Options.ThrottleUpload)-1:]); unit {\n\t\tcase \"g\", \"G\":\n\t\t\tuploadLimit = uploadLimit * 1024 * 1024 * 1024\n\t\tcase \"m\", \"M\":\n\t\t\tuploadLimit = uploadLimit * 1024 * 1024\n\t\tcase \"k\", \"K\":\n\t\t\tuploadLimit = uploadLimit * 1024\n\t\tdefault:\n\t\t\tuploadLimit, err = strconv.ParseInt(c.Options.ThrottleUpload, 10, 64)\n\t\t\tif err != nil {\n\t\t\t\tpanic(\"Could not parse given Upload Limit\")\n\t\t\t}\n\t\t}\n\n\t\trt = rate.Every(time.Second / time.Duration(uploadLimit))","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/schollz/croc/blob/e25f1bdc04f07f094d50b0a1bf67e2563944b57a/src/croc/croc.go#L257-L293","documentation":"Go panic in croc's Client setup when Options.ThrottleUpload's numeric prefix (all but the last character) cannot be parsed by strconv.ParseInt. The flag expects integer+[unit] forms like '500k'/'10m'/'2g'; anything whose prefix is not a plain integer panics. The len > 1 guard means single-character values skip this check.","triggerScenarios":"Passing --throttle-upload with a non-integer prefix: '1.5m' (ParseInt('1.5') fails on the dot), 'abc', 'k', '-m', '1e6k'.","commonSituations":"CLI users typing decimal multipliers like 1.5M (only integers are supported); scripts interpolating malformed variables; copied examples with unsupported units.","solutions":["Use an integer with a single-character unit (500k, 10m, 2g, any case) or a bare integer for bytes/sec","Avoid decimal points and multi-character units ('1.5m' and '1MB' are invalid)","Library embedders: pre-validate ThrottleUpload with strconv.ParseInt before constructing the Client so you control the error"],"exampleFix":"# before\ncroc send --throttle-upload 1.5m file.bin   # panic: prefix '1.5' is not an int\n\n# after\ncroc send --throttle-upload 1500k file.bin","handlingStrategy":"validation","validationCode":"// Go: validate before constructing the Client\nif len(opts.ThrottleUpload) > 1 && opts.IsSender {\n    prefix := opts.ThrottleUpload[:len(opts.ThrottleUpload)-1]\n    if _, err := strconv.ParseInt(prefix, 10, 64); err != nil {\n        return fmt.Errorf(\"invalid --throttle-upload %q: numeric part must be an integer\", opts.ThrottleUpload)\n    }\n}","typeGuard":"// Go\nfunc validThrottlePrefix(s string) bool {\n    if len(s) < 2 { return true }\n    _, err := strconv.ParseInt(s[:len(s)-1], 10, 64)\n    return err == nil\n}","tryCatchPattern":"// The library panics; defense is pre-validation (above) or a recover() boundary in your own goroutine/CLI wrapper that converts the panic into an error message","preventionTips":["Always use integer+unit (500k, 10m, 2g) or a bare integer","Never use decimals (1.5m) or multi-character units (MB)"],"tags":["go","panic","cli","throttling","validation"],"backgroundTag":null,"analyzedSha":"e25f1bdc04f07f094d50b0a1bf67e2563944b57a","analyzedAt":"2026-08-15T12:53:39.096Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}