vitessio/vitess · error
cannot parse uint64 from %q
Error message
cannot parse uint64 from %q
What it means
After skipping leading whitespace, parseUint64 found no parseable characters left (the string was all whitespace, or empty of digits, or only a sign that is not allowed). It returns this error quoting the original string, together with the best-effort value 0.
Source
Thrown at go/mysql/fastparse/fastparse.go:55
// 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)
}
i++
if i >= uint(len(s)) {
return 0, fmt.Errorf("cannot parse uint64 from %q", s)
}
}
d := uint64(0)
j := i
next:
for i < uint(len(s)) {View on GitHub (pinned to 01a25a7d17)
Solutions
- Trim and validate the input is a non-empty numeric string before calling ParseUint64.
- Treat the returned error as MySQL would: coerce to the returned best-effort 0 value if that matches SQL semantics, or propagate a conversion error to the client.
- If negatives are legitimate, use ParseUint64WithNeg (allowNeg=true) so "-5" parses as the 2s-complement value.
- Handle empty-string input at a higher layer (e.g. return 0 or NULL) instead of routing it to the parser.
Example fix
// before
v, err := fastparse.ParseUint64(userInput, 10)
// after
input := strings.TrimSpace(userInput)
if input == "" {
return 0, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "empty numeric value")
}
v, err := fastparse.ParseUint64(input, 10) Defensive patterns
Strategy: validation
Validate before calling
func isParseableUint(s string, allowNeg bool) bool {
s = strings.TrimSpace(s)
if s == "" {
return false
}
if s[0] == '-' {
return allowNeg && len(s) > 1
}
if s[0] == '+' {
s = s[1:]
}
if s == "" {
return false
}
for _, c := range s {
if c < '0' || c > '9' {
return false
}
}
return true
} Try / catch
v, err := fastparse.ParseUint64(s, 10)
if err != nil {
if strings.Contains(err.Error(), "cannot parse uint64") {
// match MySQL coercion semantics: use best-effort value 0
v = 0
}
} Prevention
- Trim whitespace and reject blank strings before parsing.
- Use ParseUint64WithNeg when negative values can legitimately appear.
- Decide explicitly whether empty input should be 0, NULL, or an error — do it before parsing.
- Remember fastparse returns a best-effort value alongside the error; do not use the value without checking err.
When it happens
Trigger: Calling fastparse.ParseUint64 (allowNeg=false) or ParseUint64WithNeg with strings like " ", "\t\n", "-5" when negatives are disallowed, "+" alone, or any string whose first non-space byte is not a digit (or a '-' when allowNeg is true).
Common situations: Parsing empty/blank user input or empty query parameters as numbers; SQL string values like '' or '-' converted to integers in expression evaluation; config values that are unset strings; clients sending non-numeric values where MySQL would coerce to 0 with warnings.
Related errors
- invalid base %d; must be in [2, 36]
- unexpected character %q
- invalid decimal string: %q
- stray %% at the end of pattern
- overflow
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/e7050da6134806bd.
Report an issue: GitHub.