vitessio/vitess · error

invalid base %d; must be in [2, 36]

Error message

invalid base %d; must be in [2, 36]

What it means

The fastparse package's parseUint64 supports bases 2 through 36 (matching strconv). If ParseUint64 or ParseUint64WithNeg is invoked with a base outside this range, it fails fast with this error before consuming any input. Unlike strconv, this package returns a best-effort value plus error on parse failures, but an invalid base is rejected outright with 0.

Source

Thrown at go/mysql/fastparse/fastparse.go:44

func ParseUint64(s string, base int) (uint64, error) {
	return parseUint64(s, base, false)
}

func ParseUint64WithNeg(s string, base int) (uint64, error) {
	return parseUint64(s, base, true)
}

// ParseUint64 parses uint64 from s.
//
// It is equivalent to strconv.ParseUint(s, base, 64) in case it succeeds,
// but on error it will return the best effort value of what it has parsed so far.
func parseUint64(s string, base int, allowNeg bool) (uint64, error) {
	if len(s) == 0 {
		return 0, errors.New("cannot parse uint64 from empty string")
	}
	if base < 2 || base > 36 {
		return 0, fmt.Errorf("invalid base %d; must be in [2, 36]", base)
	}
	i := uint(0)
	for i < uint(len(s)) {
		if !isSpace(s[i]) {
			break
		}
		i++
	}

	if i >= uint(len(s)) {
		return 0, fmt.Errorf("cannot parse uint64 from %q", s)
	}
	// For some reason, MySQL parses things as uint64 even with
	// a negative sign and then turns it into the 2s complement value.
	minus := s[i] == '-'
	if minus {
		if !allowNeg {
			return 0, fmt.Errorf("cannot parse uint64 from %q", s)

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Pass an explicit base between 2 and 36; use base 10 for decimal parsing.
  2. If you relied on strconv's base-0 auto-detection (0x/0b/0o prefixes), detect and strip the prefix yourself before calling with base 16/2/8.
  3. Clamp or validate any dynamic base value before passing it: if base < 2 || base > 36, handle it at the call site.

Example fix

// before
v, _ := fastparse.ParseUint64(s, 0) // base 0 not supported

// after
v, _ := fastparse.ParseUint64(s, 10)
Defensive patterns

Strategy: validation

Validate before calling

func validBase(base int) bool { return base >= 2 && base <= 36 }
// before calling:
// if !validBase(base) { return error }

Try / catch

v, err := fastparse.ParseUint64(s, base)
if err != nil {
    if strings.Contains(err.Error(), "invalid base") {
        v, err = fastparse.ParseUint64(s, 10) // fall back to decimal
    }
}

Prevention

When it happens

Trigger: Calling fastparse.ParseUint64/ParseUint64WithNeg with base < 2 (e.g. 0, 1, or the strconv special-case base 0 for auto-detection, which is NOT supported here) or base > 36.

Common situations: Porting code from strconv.ParseUint(s, 0, 64) and keeping base 0; computing the base dynamically from config or user input that yields 0 or an invalid number; typo like base 1 for "unary" parsing.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/3bba3046ea5a92e6. Report an issue: GitHub.