{"record":{"id":"5f81e0abf726b8cf","repo":"apache/beam","slug":"at-least-one-subtrigger-required-for-composite-triggers","errorCode":null,"errorMessage":"At least one subtrigger required for composite triggers.","messagePattern":"At least one subtrigger required for composite triggers\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/runtime/graphx/translate.go","lineNumber":1420,"sourceCode":"\t\treturn &pipepb.Trigger{\n\t\t\tTrigger: &pipepb.Trigger_AfterEach_{\n\t\t\t\tAfterEach: &pipepb.Trigger_AfterEach{\n\t\t\t\t\tSubtriggers: extractSubtriggers(t.Subtriggers()),\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\tdefault:\n\t\treturn &pipepb.Trigger{\n\t\t\tTrigger: &pipepb.Trigger_Default_{\n\t\t\t\tDefault: &pipepb.Trigger_Default{},\n\t\t\t},\n\t\t}\n\t}\n}\n\nfunc extractSubtriggers(t []trigger.Trigger) []*pipepb.Trigger {\n\tif len(t) <= 0 {\n\t\tpanic(\"At least one subtrigger required for composite triggers.\")\n\t}\n\n\tvar result []*pipepb.Trigger\n\tfor _, tr := range t {\n\t\tresult = append(result, makeTrigger(tr))\n\t}\n\treturn result\n}\n\nfunc makeWindowFn(w *window.Fn) (*pipepb.FunctionSpec, error) {\n\tswitch w.Kind {\n\tcase window.GlobalWindows:\n\t\treturn &pipepb.FunctionSpec{\n\t\t\tUrn: URNGlobalWindowsWindowFn,\n\t\t}, nil\n\tcase window.FixedWindows:\n\t\treturn &pipepb.FunctionSpec{\n\t\t\tUrn: URNFixedWindowsWindowFn,","sourceCodeStart":1402,"sourceCodeEnd":1438,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/graphx/translate.go#L1402-L1438","documentation":"extractSubtriggers converts a composite trigger's sub-triggers into their protobuf representation when translating a Beam pipeline graph to the runner API. Composite triggers (Always/AfterAll/AfterAny/AfterEach/AfterFirst) must contain at least one sub-trigger; the library panics rather than producing an invalid pipeline proto if the list is empty.","triggerScenarios":"Calling trigger.Always(), AfterAll, AfterAny, AfterEach or AfterFirst with zero sub-triggers (e.g. trigger.AfterAll() with no arguments) while building a pipeline windowing strategy, which then hits extractSubtriggers during graph translation.","commonSituations":"Constructing windowing strategies programmatically from a dynamic/empty list of trigger conditions; a config-driven trigger builder that yields an empty slice; refactoring that accidentally removes the single sub-trigger.","solutions":["Pass at least one sub-trigger to the composite trigger, e.g. trigger.AfterAll(trigger.AfterCount(1), trigger.AfterProcessingTime().PlusDelay(...)).","If the sub-trigger list is dynamic, guard with len check before building the windowing strategy and fall back to a default trigger.","Use trigger.DefaultTrigger() or trigger.Never() when you truly want no custom sub-triggers."],"exampleFix":"// before\nw := window.NewTrigger(window.AfterAll(subs...)) // subs is empty\n// after\nif len(subs) == 0 {\n    subs = append(subs, window.DefaultTrigger())\n}\nw := window.NewTrigger(window.AfterAll(subs...))","handlingStrategy":"validation","validationCode":"if len(subTriggers) == 0 {\n    subTriggers = []trigger.Trigger{trigger.DefaultTrigger()}\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never construct composite triggers from unvalidated dynamic lists","Default to trigger.DefaultTrigger() when no sub-triggers are configured","Add a unit test that builds every windowing strategy used in production pipelines"],"tags":["go","apache-beam","pipeline-construction","panic"],"backgroundTag":"missing-required-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}