apache/beam · error

empty slice passed as an argument to trigger.AfterAny()

Error message

empty slice passed as an argument to trigger.AfterAny()

What it means

trigger.AfterAny() builds an AfterAnyTrigger that fires when any of its subtriggers fire. The library panics when the passed slice is empty or contains only one trigger, because an 'any' combination of fewer than two triggers is meaningless — a single trigger should be used directly. It is a deliberate fail-fast guard against degenerate trigger composition.

Solutions

  1. Ensure at least two Trigger values are in the slice before calling AfterAny.
  2. If the slice may be empty, fall back to a single trigger directly (AfterFirst/AfterEnd/etc.) or a default trigger.
  3. If only one trigger is configured, return that trigger itself instead of wrapping it in AfterAny.

Example fix

// before
tr := trigger.AfterAny(subs) // panics when len(subs) <= 1
// after
var tr trigger.Trigger
switch len(subs) {
case 0:
	tr = trigger.DefaultTrigger()
case 1:
	tr = subs[0]
default:
	tr = trigger.AfterAny(subs)
}
Defensive patterns

Strategy: validation

Validate before calling

if len(subs) < 2 {
	// use a plain trigger or a default instead of AfterAny
}
tr := trigger.AfterAny(subs)

Type guard

func canAfterAny(ts []trigger.Trigger) bool { return len(ts) > 1 }

Prevention

When it happens

Trigger: Calling trigger.AfterAny(nil), trigger.AfterAny([]Trigger{}), or AfterAny with exactly one trigger (len <= 1).

Common situations: Building triggers programmatically from a slice accumulated at runtime (e.g. from config) where the slice ends up empty because no subtriggers were configured, or wrapping a single trigger 'for consistency'.

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/2169105bfb6ba920. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/core/graph/window/trigger/trigger.go:281

	subtriggers []Trigger
}

// String implements the Stringer interface and returns trigger details as a string.
func (t *AfterAnyTrigger) String() string {
	return fmt.Sprintf("%#v", t)
}

func (t AfterAnyTrigger) trigger() {}

// SubTriggers returns the component triggers.
func (t *AfterAnyTrigger) SubTriggers() []Trigger {
	return t.subtriggers
}

// AfterAny returns a new AfterAny trigger with subtriggers set to passed argument.
func AfterAny(triggers []Trigger) *AfterAnyTrigger {
	if len(triggers) <= 1 {
		panic("empty slice passed as an argument to trigger.AfterAny()")
	}
	return &AfterAnyTrigger{subtriggers: triggers}
}

// AfterAllTrigger fires after all subtriggers are fired.
type AfterAllTrigger struct {
	subtriggers []Trigger
}

// String implements the Stringer interface and returns trigger details as a string.
func (t *AfterAllTrigger) String() string {
	return fmt.Sprintf("%#v", t)
}

func (t AfterAllTrigger) trigger() {}

// SubTriggers returns the component triggers.
func (t *AfterAllTrigger) SubTriggers() []Trigger {

View on GitHub (pinned to 12126d8942)