{"record":{"id":"c7d23fea8861301b","repo":"apache/beam","slug":"typename-overflow-v-toplainstring","errorCode":null,"errorMessage":"\" + typeName + \" overflow: \" + v.toPlainString()","messagePattern":"\" \\+ typeName \\+ \" overflow: \" \\+ v\\.toPlainString\\(\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BeamRowToStorageApiProto.java","lineNumber":447,"sourceCode":"    Object value = toProtoValue(valueFieldDescriptor, valueFieldType, entryValue.getValue());\n    if (value != null) {\n      builder.setField(valueFieldDescriptor, value);\n    }\n    return builder.build();\n  }\n\n  static ByteString serializeBigDecimalToNumeric(BigDecimal o) {\n    return serializeBigDecimal(o, NUMERIC_SCALE, MAX_NUMERIC_VALUE, MIN_NUMERIC_VALUE, \"Numeric\");\n  }\n\n  private static ByteString serializeBigDecimal(\n      BigDecimal v, int scale, BigDecimal maxValue, BigDecimal minValue, String typeName) {\n    if (v.scale() > scale) {\n      throw new IllegalArgumentException(\n          typeName + \" scale cannot exceed \" + scale + \": \" + v.toPlainString());\n    }\n    if (v.compareTo(maxValue) > 0 || v.compareTo(minValue) < 0) {\n      throw new IllegalArgumentException(typeName + \" overflow: \" + v.toPlainString());\n    }\n\n    byte[] bytes = v.setScale(scale).unscaledValue().toByteArray();\n    // NUMERIC/BIGNUMERIC values are serialized as scaled integers in two's complement form in\n    // little endian\n    // order. BigInteger requires the same encoding but in big endian order, therefore we must\n    // reverse the bytes that come from the proto.\n    Bytes.reverse(bytes);\n    return ByteString.copyFrom(bytes);\n  }\n}\n","sourceCodeStart":429,"sourceCodeEnd":459,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BeamRowToStorageApiProto.java#L429-L459","documentation":"serializeBigDecimal enforces the magnitude bounds of the target BigQuery type (NUMERIC: ~1e38 precision, or BIGNUMERIC). A BigDecimal outside [minValue, maxValue] throws IllegalArgumentException, since BigQuery NUMERIC cannot represent it.","triggerScenarios":"serializeBigDecimalToNumeric (or the BIGNUMERIC variant) receives a BigDecimal whose absolute value exceeds the type's max (NUMERIC max ≈ 99999999999999999999999999999.999999999) or is below its min.","commonSituations":"Unbounded aggregates (sums of huge values), misclassified columns (NUMERIC used for data needing BIGNUMERIC/DOUBLE), or upstream data with extremely large amounts.","solutions":["Clamp or validate values upstream before the BigQuery sink","Change the BigQuery column to BIGNUMERIC or FLOAT64 and use the matching serializer","Pre-check with compareTo against MAX_NUMERIC_VALUE/MIN_NUMERIC_VALUE in pipeline code"],"exampleFix":"// before\nrow.getDecimal(\"amount\") // 1e40, overflows NUMERIC\n// after\nif (amount.compareTo(MAX_NUMERIC_VALUE) > 0) { amount = amount.setScale(0, RoundingMode.DOWN); /* or reroute */ }","handlingStrategy":"validation","validationCode":"BigDecimal max = new BigDecimal(\"99999999999999999999999999999.999999999\");\nif (value.compareTo(max) > 0 || value.compareTo(max.negate()) < 0) throw new IllegalArgumentException(\"NUMERIC overflow: \" + value);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp or fail fast on out-of-range aggregates before the sink","Use BIGNUMERIC or FLOAT64 for unbounded magnitudes","Add unit tests with extreme values for numeric pipelines"],"tags":["java","apache-beam","bigquery","numeric","overflow"],"backgroundTag":"value-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}