apache/beam · error · IllegalArgumentException
Unable to translate beam type %s to Spanner type
Error message
Unable to translate beam type %s to Spanner type
What it means
simpleBeamTypeToSpannerType maps scalar Beam field types to Cloud Spanner Type objects for schema creation. Unmapped types (everything past the supported set) raise this IllegalArgumentException. Note DATETIME is mapped to Type.timestamp(); truly unsupported types like DECIMAL or MAP hit the default branch.
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/StructUtils.java:266
case INT64:
case INT32:
case INT16:
return Type.int64();
case DOUBLE:
return Type.float64();
case FLOAT:
return Type.float32();
case DECIMAL:
return Type.numeric();
case STRING:
return Type.string();
case BOOLEAN:
return Type.bool();
// TODO: implement logical type date and timestamp
case DATETIME:
return Type.timestamp();
default:
throw new IllegalArgumentException(
String.format(
"Unable to translate beam type %s to Spanner type", beamType.getTypeName()));
}
}
private static Iterable<Type.StructField> translateRowFieldsToStructFields(
List<Schema.Field> rowFields) {
return rowFields.stream()
.map(field -> Type.StructField.of(field.getName(), beamTypeToSpannerType(field.getType())))
.collect(toList());
}
@SuppressWarnings("unchecked")
private static void addIterableToStructBuilder(
Struct.Builder structBuilder, @Nullable Iterable<Object> iterable, Schema.Field field) {
String column = field.getName();
Schema.FieldType beamIterableType = field.getType().getCollectionElementType();
if (beamIterableType == null) {View on GitHub (pinned to 12126d8942)
Solutions
- Convert the unsupported field to a supported Beam type before writing (e.g. DECIMAL to STRING, or DATETIME for timestamps).
- Pre-convert complex types (maps, bytes) to STRING/JSON-compatible representations.
- Check the supported-type list in StructUtils and adjust your Schema to match it.
Example fix
// before
Schema.Field.of("amount", Schema.FieldType.DECIMAL)
// after
Schema.Field.of("amount", Schema.FieldType.STRING) // or convert to DATETIME-compatible representation Defensive patterns
Strategy: type-guard
Type guard
boolean isSpannerWritable(Schema.FieldType t) {
switch (t.getTypeName()) {
case STRING: case INT64: case FLOAT64: case BOOLEAN: case DATETIME:
return true;
default:
return false;
}
} Prevention
- Map DECIMAL fields to STRING or FLOAT64 before Spanner writes.
- Encode maps/bytes as STRING (base64/JSON) upstream.
- Keep the write-path Schema in sync with simpleBeamTypeToSpannerType's supported set.
When it happens
Trigger: Calling beamTypeToSpannerType (e.g. when writing rows or creating Spanner tables from a Beam schema) with a Beam FieldType such as DECIMAL, BYTES, MAP, or a custom logical type not covered by simpleBeamTypeToSpannerType.
Common situations: Writing PCollections with NUMERIC/decimal columns to Spanner; schemas containing bytes or map fields; Beam logical types like Json or custom types.
Related errors
- Type '${type}' not supported.
- Error processing struct to row: {e.getMessage()}
- Unsupported beam type '%s' while translating row to struct.
- Unsupported iterable type '%s' while translating row to stru
- Could not determine array parameter type for field.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/4d22cd401f69f43d.
Report an issue: GitHub.