apache/beam · error · RuntimeException

Unsupported type " + field.getType()

Error message

Unsupported type " + field.getType()

What it means

In the default branch of fieldDescriptorFromBeamField, the field's type name is looked up in PRIMITIVE_TYPES to find the equivalent BigQuery TableFieldSchema.Type. If the Beam type is neither a known primitive nor one of the earlier-handled rows/arrays/maps/logical types, there is no BigQuery representation and the converter throws.

Source

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

              "Unexpected null element type for the map's key on " + field.getName());
        }
        if (valueType == null) {
          throw new RuntimeException(
              "Unexpected null element type for the map's value on " + field.getName());
        }

        builder =
            builder
                .setType(TableFieldSchema.Type.STRUCT)
                .addFields(fieldDescriptorFromBeamField(Field.of("key", keyType)))
                .addFields(fieldDescriptorFromBeamField(Field.of("value", valueType)))
                .setMode(TableFieldSchema.Mode.REPEATED);
        break;
      default:
        @Nullable
        TableFieldSchema.Type primitiveType = PRIMITIVE_TYPES.get(field.getType().getTypeName());
        if (primitiveType == null) {
          throw new RuntimeException("Unsupported type " + field.getType());
        }
        builder = builder.setType(primitiveType);
    }
    if (builder.getMode() != TableFieldSchema.Mode.REPEATED) {
      if (field.getType().getNullable()) {
        builder = builder.setMode(TableFieldSchema.Mode.NULLABLE);
      } else {
        builder = builder.setMode(TableFieldSchema.Mode.REQUIRED);
      }
    }
    if (field.getDescription() != null) {
      builder = builder.setDescription(field.getDescription());
    }
    return builder.build();
  }

  @Nullable
  private static Object messageValueFromRowValue(

View on GitHub (pinned to 12126d8942)

Solutions

  1. Change the offending field to a BigQuery-supported primitive (STRING, INT64, FLOAT64, NUMERIC, BOOL, BYTES, TIMESTAMP, DATE, DATETIME, TIME, GEOGRAPHY as supported).
  2. Flatten or re-shape unsupported nested types (e.g. iterable of iterable) into STRUCT/ARRAY forms BigQuery supports.
  3. If building Beam from source, add the mapping to PRIMITIVE_TYPES.
  4. Upgrade Beam - newer versions may have extended PRIMITIVE_TYPES coverage.

Example fix

// before
FieldType f = FieldType.iterator(FieldType.iterator(FieldType.int64())); // nested iterable
// after
FieldType f = FieldType.array(FieldType.array(FieldType.int64())); // ARRAY<ARRAY<INT64>> if supported, or flatten
Defensive patterns

Strategy: validation

Validate before calling

Set<Schema.TypeName> supported = Set.of(Schema.TypeName.STRING, Schema.TypeName.INT64, Schema.TypeName.INT32,
    Schema.TypeName.FLOAT, Schema.TypeName.DOUBLE, Schema.TypeName.BOOLEAN, Schema.TypeName.BYTES,
    Schema.TypeName.DATETIME, Schema.TypeName.DECIMAL, Schema.TypeName.ROW, Schema.TypeName.ARRAY, Schema.TypeName.ITERABLE, Schema.TypeName.MAP);
for (Schema.Field f : schema.getFields()) {
  if (!supported.contains(f.getType().getTypeName()))
    throw new IllegalArgumentException("Field " + f.getName() + " type unsupported: " + f.getType());
}

Type guard

boolean isBigQueryCompatible(Schema.FieldType t) {
  return PRIMITIVE_TYPES.containsKey(t.getTypeName())
      || t.getTypeName() == Schema.TypeName.ROW
      || t.getTypeName() == Schema.TypeName.ARRAY
      || t.getTypeName() == Schema.TypeName.ITERABLE
      || t.getTypeName() == Schema.TypeName.MAP
      || t.getTypeName() == Schema.TypeName.LOGICAL_TYPE;
}

Try / catch

try {
  return BeamRowToStorageApiProto.protoTableSchemaFromBeamSchema(schema);
} catch (RuntimeException e) {
  if (e.getMessage().startsWith("Unsupported type")) {
    throw new IllegalArgumentException("Reshape field for BigQuery: " + e.getMessage());
  }
  throw e;
}

Prevention

When it happens

Trigger: Converting a schema containing exotic TypeNames that PRIMITIVE_TYPES does not cover (e.g. certain BYTE/iterator/struct variants depending on Beam version, DATETIME-mismatches, or nested ITERABLE-of-ITERABLE) into a BigQuery Storage API TableSchema.

Common situations: PCollection rows with arbitrary nested Java types auto-inferred by schemas; migrating pipelines from non-BigQuery sinks; Beam versions where newer TypeNames are not yet in PRIMITIVE_TYPES.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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