apache/beam · error · IllegalArgumentException
Can't represent as
Error message
Can't represent ${fieldType} as ${avroType} What it means
Thrown by AvroUtils.genericFromBeamField when a Beam DATETIME field (backed by ReadableInstant) is converted to an Avro schema whose underlying type is neither INT (days since epoch) nor LONG (millis since epoch). Only those two Avro primitive types have a defined datetime encoding; anything else is unrepresentable.
Solutions
- Change the Avro schema for that field to type INT (dates as days since epoch) or LONG (millis since epoch)
- Convert the datetime to a string (or another supported representation) in the Beam schema before conversion, then parse it back on the Avro side
- Regenerate the Avro schema via AvroUtils.toAvroSchema(beamSchema) so DATETIME maps to the supported Avro type automatically
- If using a logical type, ensure its Avro underlying type is INT or LONG
Example fix
// before
{"name": "eventTime", "type": "string"}
// after
{"name": "eventTime", "type": {"type": "long", "logicalType": "timestamp-millis"}} Defensive patterns
Strategy: validation
Validate before calling
boolean datetimeSupported(org.apache.avro.Schema fieldSchema) {
org.apache.avro.Schema s = fieldSchema.getType() == org.apache.avro.Schema.Type.UNION
? fieldSchema.getTypes().stream().filter(t -> t.getType() != org.apache.avro.Schema.Type.NULL).findFirst().get()
: fieldSchema;
return s.getType() == org.apache.avro.Schema.Type.INT || s.getType() == org.apache.avro.Schema.Type.LONG;
} Try / catch
try {
GenericRecord record = AvroUtils.toGenericRecord(row, avroSchema);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Can't represent")) {
throw new IllegalStateException("DATETIME field must map to Avro int/long; fix schema", e);
} else { throw e; }
} Prevention
- Always back DATETIME fields with Avro int (days) or long (millis), preferably via timestamp-millis/date logical types
- Never type timestamp columns as string in .avsc files consumed by Beam
- Add a schema-compatibility unit test converting a sample Row before production runs
When it happens
Trigger: Converting a Beam Row containing a DATETIME field to a GenericRecord whose corresponding Avro schema type is, e.g., STRING, DOUBLE, or a logical type not backed by INT/LONG — typically because the Avro schema was hand-written or generated with a mismatched type for the timestamp/date column.
Common situations: Hand-edited .avsc files where a timestamp column was typed as string; schema inference from a different source (e.g. a DB schema mapping a TIMESTAMP to string); mixing Beam DATETIME with Avro logical types like local-timestamp-* that resolve to unexpected underlying types in older Avro versions.
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
- FieldType and AVRO schema don't have matching nullability
- Incorrectly sized byte array.
- Unsupported type
- Unexpected Avro field schema type
- A method marked with SchemaCreate in class
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/ba1a6654a7f5a81d.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java:1328
case STRING:
return new Utf8((String) value);
case DECIMAL:
BigDecimal decimal = (BigDecimal) value;
LogicalType logicalType = typeWithNullability.type.getLogicalType();
@SuppressWarnings("nullness")
ByteBuffer result = new Conversions.DecimalConversion().toBytes(decimal, null, logicalType);
return result;
case DATETIME:
if (typeWithNullability.type.getType() == org.apache.avro.Schema.Type.INT) {
ReadableInstant instant = (ReadableInstant) value;
return (int) Days.daysBetween(Instant.EPOCH, instant).getDays();
} else if (typeWithNullability.type.getType() == org.apache.avro.Schema.Type.LONG) {
ReadableInstant instant = (ReadableInstant) value;
return (long) instant.getMillis();
} else {
throw new IllegalArgumentException(
"Can't represent " + fieldType + " as " + typeWithNullability.type.getType());
}
case BYTES:
return ByteBuffer.wrap((byte[]) value);
case LOGICAL_TYPE:
String identifier = checkNotNull(fieldType.getLogicalType()).getIdentifier();
if (FixedBytes.IDENTIFIER.equals(identifier)) {
FixedBytesField fixedBytesField =
checkNotNull(FixedBytesField.fromBeamFieldType(fieldType));
byte[] byteArray = (byte[]) value;
if (byteArray.length != fixedBytesField.getSize()) {
throw new IllegalArgumentException("Incorrectly sized byte array.");
}
return NullnessCheckerWorkarounds.createFixed(
null, (byte[]) value, typeWithNullability.type);
} else if (VariableBytes.IDENTIFIER.equals(identifier)) {View on GitHub (pinned to 12126d8942)