{"record":{"id":"be211870690340be","repo":"apache/beam","slug":"unexpected-type-fieldtype","errorCode":null,"errorMessage":"Unexpected type ${fieldType}","messagePattern":"Unexpected type (.+?)","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":1264,"sourceCode":"        break;\n\n      case MAP:\n        if (checkNotNull(fieldType.getMapKeyType()).getTypeName().isStringType()) {\n          // Avro only supports string keys in maps.\n          baseType =\n              org.apache.avro.Schema.createMap(\n                  getFieldSchema(checkNotNull(fieldType.getMapValueType()), fieldName, namespace));\n        } else {\n          throw new IllegalArgumentException(\"Avro only supports maps with string keys\");\n        }\n        break;\n\n      case ROW:\n        baseType = toAvroSchema(checkNotNull(fieldType.getRowSchema()), fieldName, namespace);\n        break;\n\n      default:\n        throw new IllegalArgumentException(\"Unexpected type \" + fieldType);\n    }\n    return fieldType.getNullable() ? ReflectData.makeNullable(baseType) : baseType;\n  }\n\n  private static final Map<org.apache.avro.Schema, Function<Number, ? extends Number>>\n      NUMERIC_CONVERTERS =\n          ImmutableMap.of(\n              org.apache.avro.Schema.create(org.apache.avro.Schema.Type.INT), Number::intValue,\n              org.apache.avro.Schema.create(org.apache.avro.Schema.Type.LONG), Number::longValue,\n              org.apache.avro.Schema.create(org.apache.avro.Schema.Type.FLOAT), Number::floatValue,\n              org.apache.avro.Schema.create(org.apache.avro.Schema.Type.DOUBLE),\n                  Number::doubleValue);\n\n  /** Convert a value from Beam Row to a vlue used for Avro GenericRecord. */\n  private static @Nullable Object genericFromBeamField(\n      FieldType fieldType, org.apache.avro.Schema avroSchema, @Nullable Object value) {\n    TypeWithNullability typeWithNullability = new TypeWithNullability(avroSchema);\n    if (fieldType.getNullable() != typeWithNullability.nullable) {","sourceCodeStart":1246,"sourceCodeEnd":1282,"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#L1246-L1282","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)."],"exampleFix":"// before\nField.of(\"ts\", FieldType.DATETIME) // no case in the Avro converter\n// after\nField.of(\"ts\", FieldType.INT64) // encode as epoch millis, or upgrade Beam for a DATETIME mapping","handlingStrategy":"try-catch","validationCode":"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);\nstatic boolean isAvroSupported(FieldType ft) { return AVRO_SUPPORTED.contains(ft.getTypeName()); }","typeGuard":null,"tryCatchPattern":"try {\n  org.apache.avro.Schema s = AvroUtils.toAvroSchema(rowSchema);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Unexpected type \")) {\n    throw new UnsupportedOperationException(\"Field type has no Avro mapping: \" + e.getMessage(), e);\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["avro","beam","schema-conversion","unexpected-type"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}