{"record":{"id":"52b87b1358db3318","repo":"vitessio/vitess","slug":"invalid-decimal-string-q","errorCode":null,"errorMessage":"invalid decimal string: %q","messagePattern":"invalid decimal string: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/mysql/decimal/scan.go","lineNumber":262,"sourceCode":"\t\t\texpOverflow = true\n\t\tcase e < -ExponentLimit:\n\t\t\te = -ExponentLimit\n\t\t\texpOverflow = true\n\t\t}\n\t\texp += e\n\t}\n\n\td.exp = int32(exp)\n\n\tfor i < maxLen {\n\t\tif !isSpace(s[i]) {\n\t\t\tbreak\n\t\t}\n\t\ti++\n\t}\n\n\tif !num || i < maxLen || expOverflow {\n\t\terr = fmt.Errorf(\"invalid decimal string: %q\", s)\n\t}\n\treturn d, err\n}\n\nfunc mulWW(x, y big.Word) (z1, z0 big.Word) {\n\tzz1, zz0 := bits.Mul(uint(x), uint(y))\n\treturn big.Word(zz1), big.Word(zz0)\n}\n\nfunc mulAddWWW(x, y, c big.Word) (z1, z0 big.Word) {\n\tz1, zz0 := mulWW(x, y)\n\tif z0 = zz0 + c; z0 < zz0 {\n\t\tz1++\n\t}\n\treturn z1, z0\n}\n\nfunc mulAddVWW(z, x []big.Word, y, r big.Word) (c big.Word) {","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/mysql/decimal/scan.go#L244-L280","documentation":"NewFromString parses human-readable decimal text and validates that the scanned characters form a complete, well-formed decimal. If no digits were seen (`!num`), the string ended before the scan consumed it (`i < maxLen`, e.g. trailing junk or a dangling exponent), or the exponent itself overflowed, it returns this error quoting the input.","triggerScenarios":"Calling decimal.NewFromString with strings like \"abc\", \"12.3.4\", \"1e\" (dangling exponent), \"1.5abc\", \"--2\", \"\" (empty), or a number with an exponent too large for the internal representation.","commonSituations":"Parsing user or config input without prior validation; converting query results or query parameters that are not valid decimal literals; reading scientific-notation strings with unsupported exponent magnitude; application code assuming the value is always numeric.","solutions":["Check the quoted input in the error and fix the value so it matches an optional sign, digits, optional single dot, optional exponent (e.g. -123.45e10).","Pre-validate with a regexp such as ^[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?$ before calling NewFromString.","Trim whitespace and strip currency/separator characters from user input first.","Handle the error explicitly at the call site instead of ignoring it, and surface a user-friendly message."],"exampleFix":"// before\nd, err := decimal.NewFromString(input) // input = \"12.3abc\"\n\n// after\nif !decimalRe.MatchString(input) {\n    return fmt.Errorf(\"not a decimal: %q\", input)\n}\nd, err := decimal.NewFromString(input)","handlingStrategy":"validation","validationCode":"var decimalRe = regexp.MustCompile(`^[+-]?(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?$`)\nif !decimalRe.MatchString(s) {\n    return fmt.Errorf(\"not a valid decimal literal: %q\", s)\n}","typeGuard":null,"tryCatchPattern":"d, err := decimal.NewFromString(s)\nif err != nil {\n    // error already quotes the input; wrap with caller context\n    return vterrors.Wrapf(err, \"parsing decimal from user input\")\n}","preventionTips":["Always validate user/config input with a decimal regexp before parsing.","Trim whitespace and strip currency symbols/separators first.","Check exponent magnitude if scientific notation is allowed.","Never ignore the returned error — the returned Decimal is only partial on failure."],"tags":["decimal","parsing","validation","invalid-input"],"backgroundTag":"invalid-decimal-string","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}