apache/beam · error · UnsupportedOperationException

Failed to extract logical type

Error message

Failed to extract logical type

What it means

convertLogicalTypeFieldToString() asserts the field type is a logical type, then extracts the Schema.LogicalType via type.getLogicalType(). If the cast/lookup yields null, an internal invariant was violated (type claims to be logical but carries no LogicalType instance), so it throws UnsupportedOperationException("Failed to extract logical type").

Source

Thrown at sdks/java/io/singlestore/src/main/java/org/apache/beam/sdk/io/singlestore/SingleStoreDefaultUserDataMapper.java:49

/**
 * UserDataMapper that maps {@link Row} objects. ARRAYs, ITTERABLEs, MAPs and nested ROWs are not
 * supported.
 */
final class SingleStoreDefaultUserDataMapper implements SingleStoreIO.UserDataMapper<Row> {

  private final transient DateTimeFormatter formatter =
      DateTimeFormat.forPattern("yyyy-MM-DD' 'HH:mm:ss.SSS");

  private String convertLogicalTypeFieldToString(Schema.FieldType type, Object value) {
    checkArgument(
        type.getTypeName().isLogicalType(),
        "convertLogicalTypeFieldToString accepts only logical types");

    Schema.LogicalType<Object, Object> logicalType =
        (Schema.LogicalType<Object, Object>) type.getLogicalType();
    if (logicalType == null) {
      throw new UnsupportedOperationException("Failed to extract logical type");
    }

    Schema.FieldType baseType = logicalType.getBaseType();
    Object baseValue = logicalType.toBaseType(value);
    return convertFieldToString(baseType, baseValue);
  }

  private String convertFieldToString(Schema.FieldType type, Object value) {
    switch (type.getTypeName()) {
      case BYTE:
        return ((Byte) value).toString();
      case INT16:
        return ((Short) value).toString();
      case INT32:
        return ((Integer) value).toString();
      case INT64:
        return ((Long) value).toString();
      case DECIMAL:

View on GitHub (pinned to 12126d8942)

Solutions

  1. Fix the schema so logical fields carry a real LogicalType instance (verify the FieldType construction)
  2. Avoid custom logical types: convert the value to its base type in your PTransform before writing
  3. Provide a custom UserDataMapper that handles the field without relying on getLogicalType()
  4. Check Beam version for known logical-type metadata bugs and upgrade

Example fix

// before
FieldType ft = FieldType.logicalType(null); // invalid, getLogicalType()==null
// after
FieldType ft = FieldType.logicalType(MyInstantLogicalType.INSTANCE); // real LogicalType
Defensive patterns

Strategy: type-guard

Validate before calling

if (type.isLogicalType() && type.getLogicalType() == null) { throw new IllegalArgumentException("FieldType claims logical type but getLogicalType() is null"); }

Type guard

boolean hasLogicalType(Schema.FieldType t) { return t.isLogicalType() && t.getLogicalType() != null; }

Try / catch

try { mapper.mapRow(row); } catch (UnsupportedOperationException e) { if (e.getMessage().equals("Failed to extract logical type")) { /* fall back to base-type conversion */ } throw e; }

Prevention

When it happens

Trigger: A Beam Schema.FieldType with isLogicalType()==true but getLogicalType() returning null is passed to convertFieldToString on a LOGICAL_TYPE field while mapping rows for a SingleStoreIO write with the default UserDataMapper.

Common situations: Custom logical types whose getLogicalType() implementation returns null; Beam version incompatibilities where logical type metadata is dropped during schema serialization; constructing FieldType programmatically with a null logical type argument.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/07befe67c60aef34. Report an issue: GitHub.