vitessio/vitess · error
too many .s
Error message
too many .s
What it means
parseDecimal64 rejects digit strings containing more than one '.' because a decimal literal may have at most one decimal point; a second '.' makes the string invalid MySQL decimal syntax. NewFromMySQL surfaces this when decoding a value from the wire protocol.
Source
Thrown at go/mysql/decimal/scan.go:43
"math/bits"
"strings"
"vitess.io/vitess/go/mysql/fastparse"
)
var errOverflow = errors.New("overflow")
func parseDecimal64(s []byte) (Decimal, error) {
const cutoff = math.MaxUint64/10 + 1
var n uint64
dot := -1
for i, c := range s {
var d byte
switch {
case c == '.':
if dot > -1 {
return Decimal{}, errors.New("too many .s")
}
dot = i
continue
case '0' <= c && c <= '9':
d = c - '0'
default:
return Decimal{}, fmt.Errorf("unexpected character %q", c)
}
if n >= cutoff {
// n*base overflows
return Decimal{}, errOverflow
}
n *= 10
n1 := n + uint64(d)
if n1 < n {
return Decimal{}, errOverflow
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Sanitize/normalize the decimal string before parsing: keep only the first '.' and drop or reject subsequent ones
- Fix the producer that emits malformed decimals so it never concatenates fractional parts
- Validate input with a regex like ^-?\d*(\.\d+)?$ before handing it to the decimal parser
Example fix
// before
dec, err := decimal.NewFromMySQL([]byte("1.2.3")) // "too many .s"
// after
s := strings.Replace(raw, ".", "", 1) // or validate first
dec, err := decimal.NewFromMySQL([]byte(s)) Defensive patterns
Strategy: validation
Validate before calling
var decimalRe = regexp.MustCompile(`^-?\d*(\.\d+)?$`)
if !decimalRe.Match(raw) { return fmt.Errorf("invalid decimal %q", raw) } Type guard
func isWellFormedDecimal(s []byte) bool {
return bytes.Count(s, []byte{"."}) <= 1
} Try / catch
dec, err := decimal.NewFromMySQL(raw)
if err != nil && strings.Contains(err.Error(), "too many .s") {
return normalizeDecimal(raw) // keep only first '.'
} Prevention
- Never build decimal strings by concatenating fractional parts
- Normalize locale-formatted numbers ('.' vs ',') before parsing
- Validate wire/input data against a decimal regex upstream
When it happens
Trigger: parseDecimal64 iterating a byte slice that already recorded a dot position (dot > -1) and encounters another '.' character.
Common situations: Corrupted or hand-crafted wire data; upstream code that concatenated numbers (e.g. "1.2" + ".3"); locale formatting where ',' and '.' are mixed; bugs in code building decimal strings manually.
Related errors
- can't convert %s to decimal: too many .s
- overflow
- unexpected character %q
- can't convert %q to decimal: too short
- can't convert %s to decimal: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/7ad8f4b0c56bb069.
Report an issue: GitHub.