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
- Pass an explicit base between 2 and 36; use base 10 for decimal parsing.
- 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.
- 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
- Pass literal, explicit bases (usually 10) instead of computed values.
- Do not reuse strconv's base-0 convention — fastparse does not auto-detect prefixes.
- Clamp dynamic base values to [2, 36] at configuration time.
- Add a table-driven test over the bases your code uses.
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
- cannot parse uint64 from %q
- stray %% at the end of pattern
- overflow
- too many .s
- missing value for 'rate'
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/3bba3046ea5a92e6.
Report an issue: GitHub.