{"record":{"id":"04b93aa1cb1e5b83","repo":"apache/beam","slug":"unexpected-null-logical-type-field-gettype","errorCode":null,"errorMessage":"Unexpected null logical type \" + field.getType()","messagePattern":"Unexpected null logical type \" \\+ field\\.getType\\(\\)","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":249,"sourceCode":"                field.getName());\n        Preconditions.checkState(\n            !(containedTypeName.isCollectionType() || containedTypeName.isMapType()),\n            \"Nested container types are not supported by BigQuery. Field %s contains a type %s\",\n            field.getName(),\n            containedTypeName.name());\n        TableFieldSchema elementFieldSchema =\n            fieldDescriptorFromBeamField(Field.of(field.getName(), elementType));\n        builder = builder.setType(elementFieldSchema.getType());\n        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());","sourceCodeStart":231,"sourceCodeEnd":267,"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#L231-L267","documentation":"fieldDescriptorFromBeamField, for LOGICAL_TYPE fields, calls field.getType().getLogicalType() and throws \"Unexpected null logical type <field type>\" when null. A LOGICAL_TYPE FieldType must carry a LogicalType instance to map to a BigQuery TableFieldSchema.Type; a null result leaves the conversion impossible.","triggerScenarios":"A Beam Schema field declared with TypeName.LOGICAL_TYPE but constructed without a LogicalType argument (e.g. Schema.FieldType.logicalType(null) or bare logical type name), then written to BigQuery Storage API","commonSituations":"Custom logical-type handling code, schemas serialized/deserialized across job versions losing the logical-type argument, or manual FieldType construction.","solutions":["Attach the logical type: Schema.FieldType.logicalType(newyourLogicalType()) so getLogicalType() is non-null","If the underlying value is a timestamp, use Schema.FieldType.DATETIME or the Beam Timestamp logical type instead","Verify schemas aren't losing their logical-type argument during serialization between pipeline stages","Inspect the printed field.getType() in the message to see which field is malformed"],"exampleFix":"// before\nSchema.FieldType lt = Schema.FieldType.of(TypeName.LOGICAL_TYPE);\n// after\nSchema.FieldType lt = Schema.FieldType.logicalType(new SqlTypes.LocalTimestamp());","handlingStrategy":"validation","validationCode":"// Java\nfor (Schema.Field f : beamSchema.getFields()) {\n  if (f.getType().getTypeName() == TypeName.LOGICAL_TYPE && f.getType().getLogicalType() == null) {\n    throw new IllegalStateException(\"LOGICAL_TYPE field without logical type: \" + f.getName());\n  }\n}","typeGuard":"// Java\nLogicalType<?, ?> lt = fieldType.getLogicalType();\nif (lt != null) { /* safe to map to TableFieldSchema.Type */ }","tryCatchPattern":"// Java\ntry {\n  descriptor = BeamRowToStorageApiProto.protoTableSchemaFromBeamSchema(beamSchema);\n} catch (RuntimeException e) {\n  if (e.getMessage().startsWith(\"Unexpected null logical type\")) {\n    // attach the LogicalType instance to the field\n  }\n  throw e;\n}","preventionTips":["Construct logical-type fields only via Schema.FieldType.logicalType(instance)","Use built-in logical types (SqlTypes, Timestamp) rather than bare LOGICAL_TYPE TypeNames","Validate schemas after any serialization/deserialization round trip"],"tags":["java","bigquery","beam-schema","logical-type"],"backgroundTag":"schema-validation-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}