apache/beam · error · java.lang.IllegalStateException
Unreachable case for Beam typename %s
Error message
Unreachable case for Beam typename %s
What it means
fieldToAvatica switches over Beam FieldType.getTypeName() to produce JDBC-friendly values. The default branch is supposed to be unreachable because all Beam TypeNames are handled; hitting IllegalStateException("Unreachable case for Beam typename %s") means a FieldType with a TypeName the converter doesn't recognize reached the row-conversion path — typically a new/custom or logical element type added after this code was written.
Source
Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/rel/BeamEnumerableConverter.java:376
.map(elem -> fieldToAvatica(type.getCollectionElementType(), elem))
.collect(Collectors.toList());
case ITERABLE:
return StreamSupport.stream(((Iterable<?>) beamValue).spliterator(), false)
.map(elem -> fieldToAvatica(type.getCollectionElementType(), elem))
.collect(Collectors.toList());
case MAP:
return ((Map<?, ?>) beamValue)
.entrySet().stream()
.collect(
Collectors.toMap(
entry -> entry.getKey(),
entry ->
fieldToAvatica(type.getCollectionElementType(), entry.getValue())));
case ROW:
// TODO: needs to be a Struct
return beamValue;
default:
throw new IllegalStateException(
String.format("Unreachable case for Beam typename %s", type.getTypeName()));
}
}
private static Enumerable<Object> count(PipelineOptions options, BeamRelNode node) {
Pipeline pipeline = Pipeline.create(options);
BeamSqlRelUtils.toPCollection(pipeline, node).apply(ParDo.of(new RowCounter()));
PipelineResult result = pipeline.run();
long count = 0;
if (!containsUnboundedPCollection(pipeline)) {
if (PipelineResult.State.FAILED.equals(result.waitUntilFinish())) {
throw new RuntimeException("Pipeline failed for unknown reason");
}
MetricQueryResults metrics =
result
.metrics()
.queryMetrics(View on GitHub (pinned to 12126d8942)
Solutions
- Identify the offending TypeName from the message and change the column type to a supported primitive (INT32, STRING, DATETIME, etc.) in the schema
- Avoid exotic logical types in columns exposed to Beam SQL; cast/coerce to supported types upstream
- File/apply an upstream fix adding a case for the missing TypeName in fieldToAvatica
- Check Beam SDK version compatibility between the component producing the schema and the SQL extension
Example fix
// before: schema with unsupported field
Schema schema = Schema.builder().addInt64Field("id").addFieldType("x", unsupportedType).build();
// after: coerce to a supported type
Schema schema = Schema.builder().addInt64Field("id").addStringField("x").build(); Defensive patterns
Strategy: type-guard
Validate before calling
for (Field f : schema.getFields()) {
switch (f.getType().getTypeName()) {
case BYTE: case INT16: case INT32: case INT64: case FLOAT: case DOUBLE:
case STRING: case DATETIME: case BOOLEAN: case DECIMAL: case ARRAY:
case MAP: case ITERABLE: case ROW:
break;
default:
throw new IllegalArgumentException("Field '" + f.getName()
+ "' has unsupported type " + f.getType().getTypeName());
}
} Type guard
static final Set<TypeName> SUPPORTED = EnumSet.of(TypeName.BYTE, TypeName.INT16,
TypeName.INT32, TypeName.INT64, TypeName.FLOAT, TypeName.DOUBLE, TypeName.STRING,
TypeName.DATETIME, TypeName.BOOLEAN, TypeName.DECIMAL, TypeName.ARRAY,
TypeName.MAP, TypeName.ITERABLE, TypeName.ROW);
boolean isAvaticaConvertible(FieldType t) { return SUPPORTED.contains(t.getTypeName()); } Try / catch
try {
Object v = fieldToAvatica(type, value);
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Unreachable case for Beam typename")) {
// coerce value to string/primitive or skip field
} else throw e;
} Prevention
- Keep query schemas limited to primitive Beam types
- Coerce POJO/Avro-derived schemas to supported types before SELECT
- Pin consistent Beam versions across schema-producing components and the SQL extension
- Test JDBC SELECT round-trip over every column in the schema
- Track upstream Beam issues for unhandled TypeNames in fieldToAvatica
When it happens
Trigger: SELECTing a column (or nested collection/row element) whose Beam FieldType TypeName falls through the switch — e.g. a recently added Beam TypeName, an exotic logical-typed field inside arrays/maps, or a schema produced by custom IO connectors.
Common situations: Upgrading Beam SDK so schemas contain new types while the SQL extension converter lags behind; using custom logical types in table schemas queried through the JDBC/Calcite interface; returning POJO/Avro-derived schemas with unusual field types from a SELECT.
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
- The input schema must have exactly one field of type byte.
- Cannot merge two types: +fieldType1.getTypeName()+ and +fiel
- value type is '%s' for field type '%s'
- Unable to convert ${typeName}
- Unknown DateTime type ${logicalId}
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/09368bef8efc5bbb.
Report an issue: GitHub.