apache/beam · error · NullPointerException

Null collection element type at field {}

Error message

Null collection element type at field {}

What it means

addIterableToMutationBuilder needs the element type of an ITERABLE-typed field to pick the Spanner array type. If Schema.FieldType.getCollectionElementType() returns null, a NullPointerException is thrown with this message. This happens when a field is marked ITERABLE but was created without an element type.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/MutationUtils.java:324

      case ITERABLE:
        addIterableToMutationBuilder(
            mutationBuilder, row.getIterable(columnName), row.getSchema().getField(columnName));
        break;
      default:
        throw new IllegalArgumentException(
            String.format("Unsupported field type: %s", fieldType.getTypeName()));
    }
  }

  @SuppressWarnings("unchecked")
  private static void addIterableToMutationBuilder(
      Mutation.WriteBuilder mutationBuilder,
      @Nullable Iterable<Object> iterable,
      Schema.Field field) {
    String column = field.getName();
    Schema.FieldType beamIterableType = field.getType().getCollectionElementType();
    if (beamIterableType == null) {
      throw new NullPointerException("Null collection element type at field " + field.getName());
    }
    Schema.TypeName beamIterableTypeName = beamIterableType.getTypeName();
    switch (beamIterableTypeName) {
      case ROW:
        if (iterable == null) {
          mutationBuilder.set(column).toStructArray(beamTypeToSpannerType(beamIterableType), null);
        } else {
          mutationBuilder
              .set(column)
              .toStructArray(
                  beamTypeToSpannerType(beamIterableType),
                  StreamSupport.stream(iterable.spliterator(), false)
                      .map(row -> beamRowToStruct((Row) row))
                      .collect(toList()));
        }
        break;
      case INT16:
      case INT32:

View on GitHub (pinned to 12126d8942)

Solutions

  1. Fix the schema definition so every ITERABLE field specifies a concrete element type, e.g. Schema.FieldType.array(Schema.FieldType.STRING).
  2. If the schema comes from another source (avro/proto inference), verify the inferred element type is present before writing.
  3. Add a pre-write validation step that asserts each collection field has a non-null collection element type.

Example fix

// before
Schema.FieldType.iterable(null)
// after
Schema.FieldType.array(Schema.FieldType.INT64)
Defensive patterns

Strategy: validation

Validate before calling

for (Schema.Field f : row.getSchema().getFields()) {
  if (f.getType().getTypeName() == Schema.TypeName.ITERABLE
      && f.getType().getCollectionElementType() == null) {
    throw new IllegalStateException("Iterable field missing element type: " + f.getName());
  }
}

Try / catch

try { createMutationFromBeamRows(schema, row, table); } catch (NullPointerException e) { if (e.getMessage() != null && e.getMessage().contains("Null collection element type")) { /* fix schema or skip row */ } else throw e; }

Prevention

When it happens

Trigger: Writing a Beam Row to Spanner where a field's FieldType is an iterable/collection constructed without an element type (e.g. Schema.FieldType.iterable(...) given null or a malformed schema), so field.getType().getCollectionElementType() == null.

Common situations: Programmatically built schemas (or schemas deserialized from a logical plan) where the iterable element type was omitted; a schema evolution bug that stripped element type info.

Related errors


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