apache/beam · error · IllegalArgumentException
Unexpected type ${fieldType}
Error message
Unexpected type ${fieldType} What it means
This is the terminal default branch of AvroUtils.getFieldSchema: the Beam FieldType's TypeName has no case in the Beam->Avro conversion switch, so the converter throws IllegalArgumentException naming the unexpected type. It is a guard against future/unhandled FieldType variants being silently mis-converted.
Source
Thrown at sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java:1264
break;
case MAP:
if (checkNotNull(fieldType.getMapKeyType()).getTypeName().isStringType()) {
// Avro only supports string keys in maps.
baseType =
org.apache.avro.Schema.createMap(
getFieldSchema(checkNotNull(fieldType.getMapValueType()), fieldName, namespace));
} else {
throw new IllegalArgumentException("Avro only supports maps with string keys");
}
break;
case ROW:
baseType = toAvroSchema(checkNotNull(fieldType.getRowSchema()), fieldName, namespace);
break;
default:
throw new IllegalArgumentException("Unexpected type " + fieldType);
}
return fieldType.getNullable() ? ReflectData.makeNullable(baseType) : baseType;
}
private static final Map<org.apache.avro.Schema, Function<Number, ? extends Number>>
NUMERIC_CONVERTERS =
ImmutableMap.of(
org.apache.avro.Schema.create(org.apache.avro.Schema.Type.INT), Number::intValue,
org.apache.avro.Schema.create(org.apache.avro.Schema.Type.LONG), Number::longValue,
org.apache.avro.Schema.create(org.apache.avro.Schema.Type.FLOAT), Number::floatValue,
org.apache.avro.Schema.create(org.apache.avro.Schema.Type.DOUBLE),
Number::doubleValue);
/** Convert a value from Beam Row to a vlue used for Avro GenericRecord. */
private static @Nullable Object genericFromBeamField(
FieldType fieldType, org.apache.avro.Schema avroSchema, @Nullable Object value) {
TypeWithNullability typeWithNullability = new TypeWithNullability(avroSchema);
if (fieldType.getNullable() != typeWithNullability.nullable) {View on GitHub (pinned to 12126d8942)
Solutions
- Map the field to a supported Beam TypeName (primitive, ARRAY, ITERABLE, MAP, ROW) before Avro conversion.
- Upgrade the Beam Avro extension / Beam SDK so the type has a mapping.
- Convert the field manually to its Avro Schema and bypass toAvroSchema for that column.
- Catch IllegalArgumentException and skip/serialize the offending field with a custom encoding (e.g. bytes or JSON string).
Example fix
// before
Field.of("ts", FieldType.DATETIME) // no case in the Avro converter
// after
Field.of("ts", FieldType.INT64) // encode as epoch millis, or upgrade Beam for a DATETIME mapping Defensive patterns
Strategy: try-catch
Validate before calling
static final Set<TypeName> AVRO_SUPPORTED = Set.of(TypeName.BYTE, TypeName.INT16, TypeName.INT32, TypeName.INT64, TypeName.FLOAT, TypeName.DOUBLE, TypeName.BOOLEAN, TypeName.STRING, TypeName.BYTES, TypeName.DATETIME, TypeName.ARRAY, TypeName.ITERABLE, TypeName.MAP, TypeName.ROW);
static boolean isAvroSupported(FieldType ft) { return AVRO_SUPPORTED.contains(ft.getTypeName()); } Try / catch
try {
org.apache.avro.Schema s = AvroUtils.toAvroSchema(rowSchema);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unexpected type ")) {
throw new UnsupportedOperationException("Field type has no Avro mapping: " + e.getMessage(), e);
}
throw e;
} Prevention
- Keep the Beam Avro extension version aligned with the core Beam SDK version.
- Check FieldType.getTypeName() against the supported set before conversion.
- Encode exotic types as BYTES/STRING upstream of Avro sinks.
- Add a conversion smoke test covering every TypeName used in production schemas.
When it happens
Trigger: Calling toAvroSchema/getFieldSchema with a FieldType whose TypeName is not covered by the switch (e.g. certain logical/container types or newly added Beam TypeNames not yet mapped to Avro).
Common situations: Newer Beam SDKs introducing TypeNames the Avro extension doesn't handle; passing DATETIME, BYTES-adjacent exotic types, or custom-type fields through Avro sink conversion.
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
- Can't convert 'null' to FieldType
- Unhandled logical type ${identifier}
- Avro only supports maps with string keys
- Can't convert 'null' to non-nullable field
- Can't convert 'string' map keys to ${mapKeyType}
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/be211870690340be.
Report an issue: GitHub.