apache/beam · error · IllegalArgumentException

Unsupported beam type '%s' while translating row to struct.

Error message

Unsupported beam type '%s' while translating row to struct.

What it means

beamRowToStruct converts a Beam Row back into a Spanner Struct for writes/mutations. When a field's Beam type name has no case in the translation switch, this IllegalArgumentException names the unsupported Beam type. It guards the write path against types the Spanner sink cannot encode.

Source

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

              if (byteValue == null) {
                structBuilder.set(column).to((Long) null);
              } else {
                structBuilder.set(column).to(byteValue);
              }
              break;
            case BYTES:
              byte @Nullable [] bytes = row.getBytes(column);
              if (bytes == null) {
                structBuilder.set(column).to((ByteArray) null);
              } else {
                structBuilder.set(column).to(ByteArray.copyFrom(bytes));
              }
              break;
            case BOOLEAN:
              structBuilder.set(column).to(row.getBoolean(column));
              break;
            default:
              throw new IllegalArgumentException(
                  String.format(
                      "Unsupported beam type '%s' while translating row to struct.",
                      field.getType().getTypeName()));
          }
        });
    return structBuilder.build();
  }

  public static Type beamTypeToSpannerType(Schema.FieldType beamType) {
    switch (beamType.getTypeName()) {
      case ARRAY:
      case ITERABLE:
        Schema.@Nullable FieldType elementType = beamType.getCollectionElementType();
        if (elementType == null) {
          throw new NullPointerException("Null element type");
        } else {
          return Type.array(simpleBeamTypeToSpannerType(elementType));
        }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Change the offending Row field to a supported Beam type (STRING, INT64, FLOAT64, BOOLEAN, DATETIME, etc.) before conversion.
  2. Serialize the unsupported value to a supported representation (e.g. store as STRING/JSON) and parse it later.
  3. Extend the conversion switch (fork/patch StructUtils) if the type is legitimately needed.

Example fix

// before
Schema.Field.of("created", Schema.FieldType.logicalType(...))
// after
Schema.Field.of("created", Schema.FieldType.DATETIME)
Defensive patterns

Strategy: validation

Validate before calling

// check Row schema before beamRowToStruct
for (Schema.Field f : row.getSchema().getFields()) {
  Schema.TypeName t = f.getType().getTypeName();
  if (!(t == Schema.TypeName.STRING || t == Schema.TypeName.INT64 || t == Schema.TypeName.FLOAT64
        || t == Schema.TypeName.BOOLEAN || t == Schema.TypeName.DATETIME || t == Schema.TypeName.ITERABLE)) {
    throw new IllegalArgumentException("Field " + f.getName() + " has unsupported type " + t);
  }
}

Prevention

When it happens

Trigger: Passing a Beam Row whose schema contains a field type outside the supported set (e.g. logical or bytes-adjacent types not handled) into StructUtils.beamRowToStruct, including via addIterableToStructBuilder on array fields.

Common situations: PCollection schemas built programmatically with unusual field types; rows produced by upstream transforms adding custom logical types; schema drift after pipeline changes.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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