apache/beam · error · IllegalArgumentException

Unexpected timestamp type: {typeName}

Error message

Unexpected timestamp type: {typeName}

What it means

When converting a literal for a TIMESTAMP-typed field, only DATE literals, TIMESTAMP literals, or string/UNKNOWN literals are accepted. Any other literal type throws this IllegalArgumentException listing the literal's SqlTypeName.

Source

Thrown at sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/FilterUtils.java:388

          TimeString timeString = literal.getValueAs(TimeString.class);
          time = LocalTime.parse(timeString.toString());
        } else {
          throw new IllegalArgumentException("Unexpected date type: " + literal.getTypeName());
        }
        return DateTimeUtil.microsFromTime(time);
      case TIMESTAMP:
        LocalDateTime datetime;
        if (SqlTypeName.STRING_TYPES.contains(typeName) || SqlTypeName.UNKNOWN.equals(typeName)) {
          String value = literal.getValueAs(String.class);
          datetime = getLocalDateTime(value);
        } else if (SqlTypeName.DATE.equals(typeName)) {
          DateString dateString = literal.getValueAs(DateString.class);
          datetime = LocalDateTime.of(LocalDate.parse(dateString.toString()), LocalTime.MIN);
        } else if (SqlTypeName.TIMESTAMP.equals(typeName)) {
          TimestampString timestampString = literal.getValueAs(TimestampString.class);
          datetime = getLocalDateTime(timestampString.toString());
        } else {
          throw new IllegalArgumentException("Unexpected timestamp type: " + literal.getTypeName());
        }
        return DateTimeUtil.microsFromTimestamp(datetime);
      default:
        throw new IllegalArgumentException(
            String.format("Unsupported filter type in field '%s': %s", field, type));
    }
  }

  private static LocalDateTime getLocalDateTime(String value) {
    LocalDateTime datetime;
    for (DateTimeFormatter formatter : DATE_TIME_FORMATTERS) {
      try {
        datetime = LocalDateTime.parse(value, formatter);
        return datetime;
      } catch (DateTimeParseException ignored) {
        // Ignore and try the next formatter.
      }
    }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Use a SQL timestamp literal: "ts = TIMESTAMP '2024-01-01 00:00:00'", or a quoted ISO string.
  2. Convert epoch numbers to ISO-8601 strings before building the filter.
  3. Check that the field is actually TIMESTAMP in the schema and the literal type matches.

Example fix

// before
Expression e = FilterUtils.convert("ts = 1704067200", schema);
// after
Expression e = FilterUtils.convert("ts = TIMESTAMP '2024-01-01 00:00:00'", schema);
Defensive patterns

Strategy: validation

Validate before calling

checkArgument(LocalDateTime.parse(tsStr) != null, "Timestamp literal must be ISO yyyy-MM-ddTHH:mm:ss");
// build filter as: "ts = TIMESTAMP '" + tsStr.replace('T', ' ') + "'"

Try / catch

try { LocalDateTime.parse(userTs); } catch (DateTimeParseException e) { throw new IllegalArgumentException("Use ISO timestamp", e); }

Prevention

When it happens

Trigger: Calling FilterUtils.convert with a predicate like "ts = 1704067200" (integer epoch literal) or a BOOLEAN/numeric literal against a TIMESTAMP field.

Common situations: Passing Unix epoch numbers instead of timestamp literals; filters generated with numeric timestamps; copying predicates from systems where timestamps are integers.

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/02e18655dfabfd0c. Report an issue: GitHub.