apache/beam · error · UnsupportedOperationException

Unexpected Beam type: {}

Error message

Unexpected Beam type: {}

What it means

ApplyWatermarkColumn.getInstant switches on the field's Beam primitive type; only a few primitive types are supported for extracting an Instant (via their logical types). If the field's Beam type falls outside all supported cases, the default branch throws UnsupportedOperationException with the unexpected Beam type.

Source

Thrown at sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/cdc/ApplyWatermarkColumn.java:89

      case INT64:
        return Instant.ofEpochMilli(timeUnit.toMillis((Long) value));
      case DATETIME:
        return (Instant) value;
      case LOGICAL_TYPE:
        String logicalType =
            Preconditions.checkStateNotNull(field.getType().getLogicalType()).getIdentifier();
        if (logicalType.equals(SqlTypes.DATETIME.getIdentifier())) {
          return Instant.ofEpochMilli(
              MICROSECONDS.toMillis(DateTimeUtil.microsFromTimestamp((LocalDateTime) value)));
        } else if (logicalType.equals(SqlTypes.TIMESTAMP.getIdentifier())
            || logicalType.equals(org.apache.beam.sdk.schemas.logicaltypes.Timestamp.IDENTIFIER)) {
          return Instant.ofEpochMilli(
              MICROSECONDS.toMillis(DateTimeUtil.microsFromInstant((java.time.Instant) value)));
        } else {
          throw new UnsupportedOperationException("Unexpected logical type: " + logicalType);
        }
      default:
        throw new UnsupportedOperationException("Unexpected Beam type: " + field.getType());
    }
  }

  @Override
  public Duration getAllowedTimestampSkew() {
    // Generous skew to cover backfill of historical data and late-arriving CDC patterns.
    return Duration.standardDays(365);
  }
}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Point ApplyWatermarkColumn at a field whose Beam type is one of the supported timestamp variants (logical SqlTypes.TIMESTAMP / beam Timestamp).
  2. Coerce the column in an upstream transform (e.g. parse string timestamps into a proper logical timestamp field).
  3. Update ApplyWatermarkColumn to support the missing Beam type and rebuild.
  4. Verify the schema of records at runtime and align the configured watermark field with it.

Example fix

// before
.apply("watermark", ApplyWatermarkColumn.create("event_ts")); // event_ts is STRING
// after
.apply("parse-ts", MapElements.into(SqlTypes.TIMESTAMP).via(s -> Instant.parse(s)))
.apply("watermark", ApplyWatermarkColumn.create("event_ts"));
Defensive patterns

Strategy: type-guard

Validate before calling

if (!isSupportedTimestamp(schema.getField(col).getType())) {
  throw new IllegalArgumentException("Watermark column is not a timestamp-typed field: " + col);
}

Type guard

static boolean isTimestampField(Schema.Field f) {
  FieldType t = f.getType();
  return t.getTypeName().isNumericType() == false && t.getLogicalType() != null &&
      (SqlTypes.TIMESTAMP.getIdentifier().equals(t.getLogicalType().getIdentifier()) ||
       org.apache.beam.sdk.schemas.logicaltypes.Timestamp.IDENTIFIER.equals(t.getLogicalType().getIdentifier()));
}

Try / catch

try {
  records.apply(ApplyWatermarkColumn.create(col));
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Unexpected Beam type")) {
    throw new IllegalArgumentException("Watermark field must be timestamp-typed, got: " + e.getMessage());
  }
  throw e;
}

Prevention

When it happens

Trigger: A watermark field typed as a non-timestamp Beam primitive (e.g. STRING, INT64, BOOLEAN, or a nested row/array type) is supplied to ApplyWatermarkColumn, reaching the default branch of the type switch.

Common situations: Misconfigured watermark column name pointing at a string-encoded timestamp, schema drift changing the field type after a connector upgrade, or selecting the wrong column in the CDC record schema.

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


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