JuliusBrussee/caveman · error
invalid JSON number exponent
Error message
invalid JSON number exponent
What it means
parseJSONExponent parses the text after 'e'/'E' in a JSON number literal. It throws when the exponent text is completely empty — i.e. the literal ends with 'e' or 'E' and no exponent digits follow. JSON requires at least one digit in the exponent, so the library rejects it during canonicalization rather than letting Postgres reject the malformed jsonb.
Solutions
- Ensure the full number literal including exponent digits is passed in; do not split 'e' from its digits.
- Validate the literal with a standard JSON parser (encoding/json) before canonicalizing.
- If the exponent is genuinely absent, serialize the number without the exponent marker.
- Log the raw literal that failed to find the malformed producer.
Example fix
// before
lit := "1.5e" + expStr // expStr may be ""
// after
if expStr != "" { lit = "1.5e" + expStr } else { lit = "1.5" } Defensive patterns
Strategy: validation
Validate before calling
var jsonNumRe = regexp.MustCompile(`^-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?$`)
func validJSONNumber(lit string) bool { return jsonNumRe.MatchString(lit) } Try / catch
if !validJSONNumber(lit) {
return fmt.Errorf("malformed number literal %q", lit)
} Prevention
- Round-trip literals through encoding/json or strconv before canonicalizing
- Never build number strings by concatenation without validating the result
- Fail fast on the producer that emits a dangling 'e'
When it happens
Trigger: canonicalizeJSONNumber -> normalizeJSONNumber on a literal such as 1e, 2.5E, or 1e+ where the string after the exponent marker is empty. Usually means the literal was hand-built or sliced incorrectly rather than produced by a real JSON parser.
Common situations: Hand-concatenating JSON numbers (e.g. mantissa + "e" + exponent from separate config values where the exponent is missing), string manipulation of serialized numbers, template-generated JSON with empty interpolation.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- invalid JSON number
- array not closed
- assembly slot content is not JSON-serializable
- assembly slot content is not JSON-serializable
- awscreds: returned an unparseable response
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/6d802f91f608d406.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/proposalrun/proposalrun.go:272
return "", fmt.Errorf("JSON number exceeds PostgreSQL fraction-digit limit")
}
out = "0." + strings.Repeat("0", scale-len(digits)) + digits
default:
if scale > maxJSONBNumericFractionDigits || len(digits)-scale > maxJSONBNumericIntegerDigits {
return "", fmt.Errorf("JSON number exceeds PostgreSQL numeric limits")
}
point := len(digits) - scale
out = digits[:point] + "." + digits[point:]
}
if negative {
return "-" + out, nil
}
return out, nil
}
func parseJSONExponent(raw string) (int, error) {
if len(raw) == 0 {
return 0, fmt.Errorf("invalid JSON number exponent")
}
negative := false
if raw[0] == '+' || raw[0] == '-' {
negative = raw[0] == '-'
raw = raw[1:]
}
if len(raw) == 0 {
return 0, fmt.Errorf("invalid JSON number exponent")
}
value := 0
for i := 0; i < len(raw); i++ {
if raw[i] < '0' || raw[i] > '9' {
return 0, fmt.Errorf("invalid JSON number exponent")
}
digit := int(raw[i] - '0')
if value > (maxJSONBNumberExponent-digit)/10 {
return 0, fmt.Errorf("JSON number exponent exceeds supported range")
}View on GitHub (pinned to 3ee70a1026)