{"record":{"id":"1ee5a0c0a0aa8ab2","repo":"apache/beam","slug":"main-and-finally-trigger-arguments-to-trigger-orfinally","errorCode":null,"errorMessage":"main and finally trigger arguments to trigger.OrFinally() cannot be nil","messagePattern":"main and finally trigger arguments to trigger\\.OrFinally\\(\\) cannot be nil","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/window/trigger/trigger.go","lineNumber":329,"sourceCode":"// OrFinallyTrigger is ready whenever either of its subtriggers are ready, but finishes output\n// when the finally subtrigger fires.\ntype OrFinallyTrigger struct {\n\tmain    Trigger // Trigger governing main output; may fire repeatedly.\n\tfinally Trigger // Trigger governing termination of output.\n}\n\n// String implements the Stringer interface and returns trigger details as a string.\nfunc (t *OrFinallyTrigger) String() string {\n\treturn fmt.Sprintf(\"%#v\", t)\n}\n\nfunc (t OrFinallyTrigger) trigger() {}\n\n// OrFinally trigger has main trigger which may fire repeatedly and the finally trigger.\n// Output is produced when the finally trigger fires.\nfunc OrFinally(main, finally Trigger) *OrFinallyTrigger {\n\tif main == nil || finally == nil {\n\t\tpanic(\"main and finally trigger arguments to trigger.OrFinally() cannot be nil\")\n\t}\n\treturn &OrFinallyTrigger{main: main, finally: finally}\n}\n\n// Main returns the main trigger of OrFinallyTrigger.\nfunc (t *OrFinallyTrigger) Main() Trigger {\n\treturn t.main\n}\n\n// Finally returns the finally trigger of OrFinallyTrigger.\nfunc (t *OrFinallyTrigger) Finally() Trigger {\n\treturn t.finally\n}\n\n// NeverTrigger is never ready to fire.\ntype NeverTrigger struct{}\n\n// String implements the Stringer interface and returns trigger details as a string.","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/window/trigger/trigger.go#L311-L347","documentation":"OrFinally combines a main trigger (which may fire repeatedly) with a finally trigger that ends output. Both arguments must be non-nil; passing either as nil is a programming error, so the constructor panics rather than returning a broken trigger.","triggerScenarios":"Calling trigger.OrFinally(nil, finally), OrFinally(main, nil), or OrFinally(nil, nil), typically because a variable holding a trigger was never initialized or a factory function returned nil.","commonSituations":"Conditionally building triggers where an if-branch forgets to assign the trigger, or a lookup/config parse returns nil and the nil is passed straight through.","solutions":["Check both triggers for nil before calling OrFinally and substitute valid triggers.","Trace why the trigger variable is nil — usually an unassigned branch or a factory returning nil on error.","Return a default trigger when configuration yields none."],"exampleFix":"// before\nt := trigger.OrFinally(main, fin) // panics if either is nil\n// after\nif main == nil {\n\tmain = trigger.DefaultTrigger()\n}\nif fin == nil {\n\tfin = trigger.AfterEndOfWindow()\n}\nt := trigger.OrFinally(main, fin)","handlingStrategy":"validation","validationCode":"if main == nil || fin == nil {\n\treturn fmt.Errorf(\"OrFinally requires non-nil main and finally triggers\")\n}\nt := trigger.OrFinally(main, fin)","typeGuard":"func validOrFinallyArgs(main, fin trigger.Trigger) bool { return main != nil && fin != nil }","tryCatchPattern":null,"preventionTips":["Treat nil triggers as invalid config and substitute defaults at load time.","Make trigger factory functions return (Trigger, error) instead of bare nil.","Initialize trigger variables in all conditional branches."],"tags":["go","panic","beam","trigger","nil-argument"],"backgroundTag":"null-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"}