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

  1. Use an integer with a single-character unit (500k, 10m, 2g, any case) or a bare integer for bytes/sec
  2. Avoid decimal points and multi-character units ('1.5m' and '1MB' are invalid)
  3. 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

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


AI-assisted analysis of schollz/croc@e25f1bdc04 (2026-08-15). Data as JSON: /api/errors/c7f5feb0db3e57d2. Report an issue: GitHub.