apache/beam · error

AfterProcessingTime trigger set without a delay or alignment

Error message

AfterProcessingTime trigger set without a delay or alignment.

What it means

An AfterProcessingTime trigger must be configured with at least one timestamp transform (a delay or a repeat/alignment). A trigger with no transforms has no meaningful firing semantics in the portable representation, so makeTrigger panics.

Source

Thrown at sdks/go/pkg/beam/core/runtime/graphx/translate.go:1326

	case *trigger.AfterAnyTrigger:
		return &pipepb.Trigger{
			Trigger: &pipepb.Trigger_AfterAny_{
				AfterAny: &pipepb.Trigger_AfterAny{
					Subtriggers: extractSubtriggers(t.SubTriggers()),
				},
			},
		}
	case *trigger.AfterAllTrigger:
		return &pipepb.Trigger{
			Trigger: &pipepb.Trigger_AfterAll_{
				AfterAll: &pipepb.Trigger_AfterAll{
					Subtriggers: extractSubtriggers(t.SubTriggers()),
				},
			},
		}
	case *trigger.AfterProcessingTimeTrigger:
		if len(t.TimestampTransforms()) == 0 {
			panic("AfterProcessingTime trigger set without a delay or alignment.")
		}
		tts := []*pipepb.TimestampTransform{}
		for _, tt := range t.TimestampTransforms() {
			var ttp *pipepb.TimestampTransform
			switch tt := tt.(type) {
			case trigger.DelayTransform:
				ttp = &pipepb.TimestampTransform{
					TimestampTransform: &pipepb.TimestampTransform_Delay_{
						Delay: &pipepb.TimestampTransform_Delay{DelayMillis: tt.Delay},
					}}
			case trigger.AlignToTransform:
				ttp = &pipepb.TimestampTransform{
					TimestampTransform: &pipepb.TimestampTransform_AlignTo_{
						AlignTo: &pipepb.TimestampTransform_AlignTo{
							Period: tt.Period,
							Offset: tt.Offset,
						},
					}}

View on GitHub (pinned to 12126d8942)

Solutions

  1. Configure the trigger with trigger.Delay(...) (e.g. AfterProcessingTime().Delay(10*time.Second)) or an alignment transform
  2. Add at least one TimestampTransform before running the pipeline
  3. Check trigger construction helpers to ensure transforms are appended

Example fix

// before
t := trigger.NewAfterProcessingTimeTrigger()
// after
t := trigger.NewAfterProcessingTimeTrigger().Delay(10 * time.Second)
Defensive patterns

Strategy: validation

Validate before calling

t := trigger.NewAfterProcessingTimeTrigger()
if len(t.TimestampTransforms()) == 0 { return errors.New("AfterProcessingTime trigger needs a delay or alignment") }

Try / catch

defer func() { if r := recover(); r != nil { err = fmt.Errorf("trigger marshaling: %v", r) } }()

Prevention

When it happens

Trigger: Constructing trigger.NewAfterProcessingTimeTrigger() with no calls to Delay/AlignTo/RepeatAtIndex-style transforms and marshaling the windowing strategy via MarshalWindowingStrategy/makeTrigger (including nested subtriggers).

Common situations: Building triggers programmatically and forgetting the Delay(...) call; constructing an empty trigger then adding subtriggers only; refactor dropping the delay configuration.

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/23649959c81be3a4. Report an issue: GitHub.