apache/beam · error · IllegalArgumentException

Required field 'timestamp_transform' not set in %s

Error message

Required field 'timestamp_transform' not set in %s

What it means

TriggerTranslation.fromProto converts a RunnerApi.TimestampTransform proto into Java triggers. If the oneof timestamp_transform was never set (case TIMESTAMPTRANSFORM_NOT_SET), there is no transform to translate, so an IllegalArgumentException is thrown.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/TriggerTranslation.java:255

          return AfterWatermark.pastEndOfWindow()
              .withLateFirings((OnceTrigger) fromProto(eowProto.getLateFirings()));
        }
      case AFTER_PROCESSING_TIME:
        AfterProcessingTime trigger = AfterProcessingTime.pastFirstElementInPane();
        for (RunnerApi.TimestampTransform transform :
            triggerProto.getAfterProcessingTime().getTimestampTransformsList()) {
          switch (transform.getTimestampTransformCase()) {
            case ALIGN_TO:
              trigger =
                  trigger.alignedTo(
                      Duration.millis(transform.getAlignTo().getPeriod()),
                      new Instant(transform.getAlignTo().getOffset()));
              break;
            case DELAY:
              trigger = trigger.plusDelayOf(Duration.millis(transform.getDelay().getDelayMillis()));
              break;
            case TIMESTAMPTRANSFORM_NOT_SET:
              throw new IllegalArgumentException(
                  String.format("Required field 'timestamp_transform' not set in %s", transform));
            default:
              throw new IllegalArgumentException(
                  String.format(
                      "Unknown timestamp transform case: %s",
                      transform.getTimestampTransformCase()));
          }
        }
        return trigger;
      case AFTER_SYNCHRONIZED_PROCESSING_TIME:
        return AfterSynchronizedProcessingTime.ofFirstElement();
      case ALWAYS:
        return new ReshuffleTrigger();
      case ELEMENT_COUNT:
        return AfterPane.elementCountAtLeast(triggerProto.getElementCount().getElementCount());
      case NEVER:
        return Never.ever();
      case OR_FINALLY:

View on GitHub (pinned to 12126d8942)

Solutions

  1. Set one of the timestamp_transform variants when building the proto (setDelay, setAlignTo, or setTruncate)
  2. Regenerate the pipeline proto from valid trigger construction code
  3. Validate the proto's TimestampTransformCase before calling fromProto

Example fix

// before
TimestampTransform.newBuilder().build();
// after
TimestampTransform.newBuilder()
    .setDelay(TimestampTransform.Delay.newBuilder().setDelayMillis(1000))
    .build();
Defensive patterns

Strategy: type-guard

Validate before calling

if (transform.getTimestampTransformCase() == TimestampTransform.TimestampTransformCase.TIMESTAMPTRANSFORM_NOT_SET) {
  throw new IllegalStateException("timestamp_transform must be set");
}

Type guard

boolean hasTimestampTransform(TimestampTransform t) {
  return t.getTimestampTransformCase() != TimestampTransformCase.TIMESTAMPTRANSFORM_NOT_SET;
}

Try / catch

try {
  TriggerTranslation.fromProto(triggerProto);
} catch (IllegalArgumentException e) {
  // handle unset timestamp_transform oneof
}

Prevention

When it happens

Trigger: Deserializing a pipeline proto where a TimestampTransform message exists but no variant (truncate/delay/alignTo) was populated.

Common situations: Protos built programmatically without calling the setter; serialization dropping unset oneof fields; hand-crafted or corrupted pipeline files.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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