{"record":{"id":"30fe4f94b6f8b129","repo":"apache/beam","slug":"typename-scale-cannot-exceed-scale-v-toplainstring","errorCode":null,"errorMessage":"\" + typeName + \" scale cannot exceed \" + scale + \": \" + v.toPlainString()","messagePattern":"\" \\+ typeName \\+ \" scale cannot exceed \" \\+ scale \\+ \": \" \\+ 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":443,"sourceCode":"    }\n    FieldDescriptor valueFieldDescriptor =\n        Preconditions.checkNotNull(descriptor.findFieldByName(\"value\"));\n    @Nullable\n    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":425,"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#L425-L459","documentation":"When serializing a BigDecimal for a BigQuery NUMERIC column, serializeBigDecimal rejects values whose decimal scale (fraction digits) exceeds the allowed NUMERIC_SCALE of 9. This is a data-precondition enforced because BigQuery NUMERIC cannot store more than 9 decimal places.","triggerScenarios":"serializeBigDecimalToNumeric receives a BigDecimal with scale > 9, e.g. produced by computations like division or averaging inside the pipeline before writing to BigQuery NUMERIC.","commonSituations":"Pipelines computing averages or interest rates produce values like 0.1234567891; BigQuery sink then fails. Common when upstream data or calc precision is not rounded/truncated before the sink.","solutions":["Round/truncate the value before the sink: value.setScale(9, RoundingMode.HALF_UP)","Use BIGNUMERIC column type via the corresponding serializer if more scale is needed","Validate/sanitize BigDecimal scales in a transform upstream of the BigQueryIO write"],"exampleFix":"// before\nBigDecimal rate = numerator.divide(denominator);\nrow.getDecimal(\"rate\")\n// after\nBigDecimal rate = numerator.divide(denominator, 9, RoundingMode.HALF_UP);","handlingStrategy":"validation","validationCode":"if (value.scale() > 9) { value = value.setScale(9, RoundingMode.HALF_UP); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always setScale before writing BigDecimal to NUMERIC","Use explicit RoundingMode in division operations","Prefer BIGNUMERIC when more than 9 fractional digits are required"],"tags":["java","apache-beam","bigquery","numeric","decimal"],"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"}