apache/beam · error · RuntimeException

Unexpected null element type on " + field.getName()

Error message

Unexpected null element type on " + field.getName()

What it means

fieldDescriptorFromBeamField, for ARRAY or ITERABLE fields, calls field.getType().getCollectionElementType() and throws "Unexpected null element type on <field name>" when null. A collection-typed FieldType must declare its element type to build the BigQuery REPEATED field schema.

Solutions

  1. Create collection fields with an element type: Schema.FieldType.array(elementType) or iterable(elementType)
  2. Validate all collection fields' getCollectionElementType() before invoking the write
  3. Fix schema-inference code to always pass the contained type
  4. Check the named field (in the message) to locate the malformed schema entry

Example fix

// before
Schema.FieldType listType = Schema.FieldType.of(TypeName.ARRAY); // no element
// after
Schema.FieldType listType = Schema.FieldType.array(Schema.FieldType.STRING);
Defensive patterns

Strategy: validation

Validate before calling

// Java
for (Schema.Field f : beamSchema.getFields()) {
  TypeName tn = f.getType().getTypeName();
  if ((tn == TypeName.ARRAY || tn == TypeName.ITERABLE) && f.getType().getCollectionElementType() == null) {
    throw new IllegalStateException("Collection field without element type: " + f.getName());
  }
}

Type guard

// Java
FieldType el = fieldType.getCollectionElementType();
if (el != null) { /* safe to map element schema */ }

Try / catch

// Java
try {
  descriptor = BeamRowToStorageApiProto.protoTableSchemaFromBeamSchema(beamSchema);
} catch (RuntimeException e) {
  if (e.getMessage().startsWith("Unexpected null element type on")) {
    // fix the named field's element type
  }
  throw e;
}

Prevention

When it happens

Trigger: A Beam Schema field declared ARRAY/ITERABLE without an element type (e.g. FieldType.of(TypeName.ARRAY) constructed manually), then written to BigQuery via Storage API

Common situations: Programmatic schema construction, schema inference frameworks emitting bare collection type names, or schemas built before Beam enforced element-type arguments.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/7eb8664b7485aaf5. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BeamRowToStorageApiProto.java:225

    }
    builder = builder.setName(field.getName().toLowerCase());

    switch (field.getType().getTypeName()) {
      case ROW:
        @Nullable Schema rowSchema = field.getType().getRowSchema();
        if (rowSchema == null) {
          throw new RuntimeException("Unexpected null schema!");
        }
        builder = builder.setType(TableFieldSchema.Type.STRUCT);
        for (Schema.Field nestedField : rowSchema.getFields()) {
          builder = builder.addFields(fieldDescriptorFromBeamField(nestedField));
        }
        break;
      case ARRAY:
      case ITERABLE:
        @Nullable FieldType elementType = field.getType().getCollectionElementType();
        if (elementType == null) {
          throw new RuntimeException("Unexpected null element type on " + field.getName());
        }
        TypeName containedTypeName =
            Preconditions.checkNotNull(
                elementType.getTypeName(),
                "Null type name found in contained type at %s",
                field.getName());
        Preconditions.checkState(
            !(containedTypeName.isCollectionType() || containedTypeName.isMapType()),
            "Nested container types are not supported by BigQuery. Field %s contains a type %s",
            field.getName(),
            containedTypeName.name());
        TableFieldSchema elementFieldSchema =
            fieldDescriptorFromBeamField(Field.of(field.getName(), elementType));
        builder = builder.setType(elementFieldSchema.getType());
        if (elementFieldSchema.hasTimestampPrecision()) {
          builder = builder.setTimestampPrecision(elementFieldSchema.getTimestampPrecision());
        }
        builder.addAllFields(elementFieldSchema.getFieldsList());

View on GitHub (pinned to 12126d8942)