schollz/croc · critical
Could not parse given Upload Limit
Error message
Could not parse given Upload Limit
What it means
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.
Source
Thrown at src/croc/croc.go:275
codeComponents, err := codephrase.Parse(c.Options.SharedSecret)
if err != nil {
return
}
c.Options.RoomName = codeComponents.RoomName
c.pakePassphrase = codeComponents.PAKEPassphrase
c.baseRoomName = c.Options.RoomName
c.reconnectVersion = ReconnectVersion
c.conn = make([]*comm.Comm, 16)
// initialize throttler
if len(c.Options.ThrottleUpload) > 1 && c.Options.IsSender {
upload := c.Options.ThrottleUpload[:len(c.Options.ThrottleUpload)-1]
var uploadLimit int64
uploadLimit, err = strconv.ParseInt(upload, 10, 64)
if err != nil {
panic("Could not parse given Upload Limit")
}
minBurstSize := models.TCP_BUFFER_SIZE
var rt rate.Limit
switch unit := string(c.Options.ThrottleUpload[len(c.Options.ThrottleUpload)-1:]); unit {
case "g", "G":
uploadLimit = uploadLimit * 1024 * 1024 * 1024
case "m", "M":
uploadLimit = uploadLimit * 1024 * 1024
case "k", "K":
uploadLimit = uploadLimit * 1024
default:
uploadLimit, err = strconv.ParseInt(c.Options.ThrottleUpload, 10, 64)
if err != nil {
panic("Could not parse given Upload Limit")
}
}
rt = rate.Every(time.Second / time.Duration(uploadLimit))View on GitHub (pinned to e25f1bdc04)
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
Example fix
# before croc send --throttle-upload 1.5m file.bin # panic: prefix '1.5' is not an int # after croc send --throttle-upload 1500k file.bin
Defensive patterns
Strategy: validation
Validate before calling
// Go: validate before constructing the Client
if len(opts.ThrottleUpload) > 1 && opts.IsSender {
prefix := opts.ThrottleUpload[:len(opts.ThrottleUpload)-1]
if _, err := strconv.ParseInt(prefix, 10, 64); err != nil {
return fmt.Errorf("invalid --throttle-upload %q: numeric part must be an integer", opts.ThrottleUpload)
}
} Type guard
// Go
func validThrottlePrefix(s string) bool {
if len(s) < 2 { return true }
_, err := strconv.ParseInt(s[:len(s)-1], 10, 64)
return err == nil
} Try / catch
// 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
Prevention
- Always use integer+unit (500k, 10m, 2g) or a bare integer
- Never use decimals (1.5m) or multi-character units (MB)
When it happens
Trigger: Passing --throttle-upload with a non-integer prefix: '1.5m' (ParseInt('1.5') fails on the dot), 'abc', 'k', '-m', '1e6k'.
Common situations: CLI users typing decimal multipliers like 1.5M (only integers are supported); scripts interpolating malformed variables; copied examples with unsupported units.
Related errors
- not enough open ports to run local relay
- Code must be at least 6 characters
- Custom codes must use printable ASCII characters
- Choose at least one file
- Duplicate filename: ${outgoingName}
AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15).
Data as JSON: /api/errors/c7f5feb0db3e57d2.
Report an issue: GitHub.