jackc/pgx · error

is not a number

Error message

%s is not a number

What it means

parseNumericString decomposes a decimal string into a big.Int mantissa and exponent; after stripping the decimal point it calls big.Int.SetString. This guard fires when that parse reports failure — the remaining string (with '.' removed and trailing zeros possibly trimmed) is not a valid signed integer literal, so the input was never a well-formed number.

Solutions

  1. Validate that the source string is a plain decimal number before parsing
  2. Reject or sanitize inputs like '1.2.3', 'abc', or empty strings upstream
  3. For JSON input, ensure the field is a JSON number, not a string with stray characters
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pgtype/numeric.go:199 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04). Data as JSON: /api/errors/bc08abb3a00cd708. Report an issue: GitHub.

Appendix: source

Thrown at pgtype/numeric.go:199

	return num, nil
}

func parseNumericString(str string) (n *big.Int, exp int32, err error) {
	idx := strings.IndexByte(str, '.')

	if idx == -1 {
		for len(str) > 1 && str[len(str)-1] == '0' && str[len(str)-2] != '-' {
			str = str[:len(str)-1]
			exp++
		}
	} else {
		exp = int32(-(len(str) - idx - 1))
		str = str[:idx] + str[idx+1:]
	}

	accum := &big.Int{}
	if _, ok := accum.SetString(str, 10); !ok {
		return nil, 0, fmt.Errorf("%s is not a number", str)
	}

	return accum, exp, nil
}

// nbaseDigitsToInt64 reads up to 4 nbase digits and packs them into an int64.
// It stops early at digitsLeft or at the end of r, whichever comes first.
func nbaseDigitsToInt64(r *pgio.Reader, digitsLeft int) (accum int64, digitsRead int) {
	digits := min(digitsLeft, r.Remaining()/2, 4)

	for i := range digits {
		if i > 0 {
			accum *= nbase
		}
		accum += int64(r.Uint16())
	}

	return accum, digits

View on GitHub (pinned to ec1a0befd2)