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

  1. Ensure the full number literal including exponent digits is passed in; do not split 'e' from its digits.
  2. Validate the literal with a standard JSON parser (encoding/json) before canonicalizing.
  3. If the exponent is genuinely absent, serialize the number without the exponent marker.
  4. 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

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.

Related errors


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)