{"record":{"id":"ba1a6654a7f5a81d","repo":"apache/beam","slug":"can-t-represent-fieldtype-as-avrotype","errorCode":null,"errorMessage":"Can't represent ${fieldType} as ${avroType}","messagePattern":"Can't represent (.+?) as (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java","lineNumber":1328,"sourceCode":"      case STRING:\n        return new Utf8((String) value);\n\n      case DECIMAL:\n        BigDecimal decimal = (BigDecimal) value;\n        LogicalType logicalType = typeWithNullability.type.getLogicalType();\n        @SuppressWarnings(\"nullness\")\n        ByteBuffer result = new Conversions.DecimalConversion().toBytes(decimal, null, logicalType);\n        return result;\n\n      case DATETIME:\n        if (typeWithNullability.type.getType() == org.apache.avro.Schema.Type.INT) {\n          ReadableInstant instant = (ReadableInstant) value;\n          return (int) Days.daysBetween(Instant.EPOCH, instant).getDays();\n        } else if (typeWithNullability.type.getType() == org.apache.avro.Schema.Type.LONG) {\n          ReadableInstant instant = (ReadableInstant) value;\n          return (long) instant.getMillis();\n        } else {\n          throw new IllegalArgumentException(\n              \"Can't represent \" + fieldType + \" as \" + typeWithNullability.type.getType());\n        }\n\n      case BYTES:\n        return ByteBuffer.wrap((byte[]) value);\n\n      case LOGICAL_TYPE:\n        String identifier = checkNotNull(fieldType.getLogicalType()).getIdentifier();\n        if (FixedBytes.IDENTIFIER.equals(identifier)) {\n          FixedBytesField fixedBytesField =\n              checkNotNull(FixedBytesField.fromBeamFieldType(fieldType));\n          byte[] byteArray = (byte[]) value;\n          if (byteArray.length != fixedBytesField.getSize()) {\n            throw new IllegalArgumentException(\"Incorrectly sized byte array.\");\n          }\n          return NullnessCheckerWorkarounds.createFixed(\n              null, (byte[]) value, typeWithNullability.type);\n        } else if (VariableBytes.IDENTIFIER.equals(identifier)) {","sourceCodeStart":1310,"sourceCodeEnd":1346,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java#L1310-L1346","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n{\"name\": \"eventTime\", \"type\": \"string\"}\n// after\n{\"name\": \"eventTime\", \"type\": {\"type\": \"long\", \"logicalType\": \"timestamp-millis\"}}","handlingStrategy":"validation","validationCode":"boolean datetimeSupported(org.apache.avro.Schema fieldSchema) {\n  org.apache.avro.Schema s = fieldSchema.getType() == org.apache.avro.Schema.Type.UNION\n      ? fieldSchema.getTypes().stream().filter(t -> t.getType() != org.apache.avro.Schema.Type.NULL).findFirst().get()\n      : fieldSchema;\n  return s.getType() == org.apache.avro.Schema.Type.INT || s.getType() == org.apache.avro.Schema.Type.LONG;\n}","typeGuard":null,"tryCatchPattern":"try {\n  GenericRecord record = AvroUtils.toGenericRecord(row, avroSchema);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Can't represent\")) {\n    throw new IllegalStateException(\"DATETIME field must map to Avro int/long; fix schema\", e);\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["java","avro","beam-schema","datetime","conversion"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}