{"record":{"id":"6becfa3d99a69ce4","repo":"apache/beam","slug":"unsupported-precision-for-timestamp-logical-type-precision","errorCode":null,"errorMessage":"Unsupported precision for Timestamp logical type \" + precision","messagePattern":"Unsupported precision for Timestamp logical type \" \\+ precision","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BeamRowToStorageApiProto.java","lineNumber":258,"sourceCode":"        if (elementFieldSchema.hasTimestampPrecision()) {\n          builder = builder.setTimestampPrecision(elementFieldSchema.getTimestampPrecision());\n        }\n        builder.addAllFields(elementFieldSchema.getFieldsList());\n        builder = builder.setMode(TableFieldSchema.Mode.REPEATED);\n        break;\n      case LOGICAL_TYPE:\n        @Nullable LogicalType<?, ?> logicalType = field.getType().getLogicalType();\n        if (logicalType == null) {\n          throw new RuntimeException(\"Unexpected null logical type \" + field.getType());\n        }\n        @Nullable TableFieldSchema.Type type;\n        if (logicalType.getIdentifier().equals(Timestamp.IDENTIFIER)) {\n          int precision =\n              Preconditions.checkNotNull(\n                  logicalType.getArgument(),\n                  \"Expected logical type argument for timestamp precision.\");\n          if (precision != 9) {\n            throw new RuntimeException(\n                \"Unsupported precision for Timestamp logical type \" + precision);\n          }\n          // Map Timestamp.NANOS logical type to BigQuery TIMESTAMP(12) for nanosecond precision\n          type = TableFieldSchema.Type.TIMESTAMP;\n          builder.setTimestampPrecision(Int64Value.newBuilder().setValue(12L).build());\n        } else {\n          type = LOGICAL_TYPES.get(logicalType.getIdentifier());\n          if (type == null) {\n            throw new RuntimeException(\"Unsupported logical type \" + field.getType());\n          }\n        }\n        builder = builder.setType(type);\n        break;\n      case MAP:\n        @Nullable FieldType keyType = field.getType().getMapKeyType();\n        @Nullable FieldType valueType = field.getType().getMapValueType();\n        if (keyType == null) {\n          throw new RuntimeException(","sourceCodeStart":240,"sourceCodeEnd":276,"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#L240-L276","documentation":"BeamRowToStorageApiProto converts a Beam Schema/Row into a BigQuery Storage API TableSchema/protobuf message. The Beam Timestamp logical type carries a precision argument; this converter only supports nanosecond precision (9 fractional digits, Timestamp.NANOS). Any other precision is rejected because BigQuery's storage-write mapping here only defines behavior for that case.","triggerScenarios":"Building a TableSchema via BeamRowToStorageApiProto.protoTableSchemaFromBeamSchema (or elementFieldSchema) for a Beam schema whose field is a Timestamp logical type with an argument other than 9, e.g. Timestamp.of(TimeUnit.MICROSECONDS) or custom precision.","commonSituations":"Users declaring a schema field with FieldType.logicalType(Timestamp.of(TimeUnit.MICROSECONDS)) or the default microsecond-precision timestamp, then writing to BigQuery via the Storage Write API sink.","solutions":["Use the nanosecond Timestamp logical type: FieldType.logicalType(Timestamp.of(TimeUnit.NANOSECONDS)) (precision 9).","If micro/milli precision suffices, use a plain DATETIME/datetime type or a non-logical type instead of the Timestamp logical type.","If you own the pipeline, catch/translate the RuntimeException at schema-construction time and fall back to a supported field type.","Check the Beam version: newer releases may support more precisions; upgrade sdks/java/io/google-cloud-platform."],"exampleFix":"// before\nFieldType ts = FieldType.logicalType(Timestamp.of(TimeUnit.MICROSECONDS));\n// after\nFieldType ts = FieldType.logicalType(Timestamp.of(TimeUnit.NANOSECONDS));","handlingStrategy":"validation","validationCode":"for (Schema.Field f : schema.getFields()) {\n  if (f.getType().getTypeName() == Schema.TypeName.LOGICAL_TYPE) {\n    LogicalType<?, ?> lt = f.getType().getLogicalType();\n    if (lt != null && lt.getIdentifier().equals(Timestamp.IDENTIFIER)\n        && !Integer.valueOf(9).equals((Integer) lt.getArgument())) {\n      throw new IllegalArgumentException(\"Field \" + f.getName() + \" must use Timestamp NANOS precision (9)\");\n    }\n  }\n}","typeGuard":"boolean isSupportedTimestamp(Schema.FieldType t) {\n  return t.getTypeName() != Schema.TypeName.LOGICAL_TYPE\n      || !(t.getLogicalType() instanceof Timestamp)\n      || ((Integer) t.getLogicalType().getArgument()) == 9;\n}","tryCatchPattern":"try {\n  TableSchema ts = BeamRowToStorageApiProto.protoTableSchemaFromBeamSchema(schema);\n} catch (RuntimeException e) {\n  if (e.getMessage().startsWith(\"Unsupported precision for Timestamp\")) {\n    schema = normalizeTimestampPrecision(schema); // rewrite fields to NANOS\n  } else { throw e; }\n}","preventionTips":["Always declare timestamps as Timestamp.of(TimeUnit.NANOSECONDS) for BigQuery Storage Write","Centralize schema definitions so field types are defined once","Run schema validation in a unit test before deploying the pipeline"],"tags":["java","apache-beam","bigquery","schema-mapping"],"backgroundTag":"unsupported-config-value","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"}