{"record":{"id":"d7aa3d089fe0b26c","repo":"apache/beam","slug":"trigger-aftercount-v-must-be-a-positive-integer","errorCode":null,"errorMessage":"trigger.AfterCount(%v) must be a positive integer","messagePattern":"trigger\\.AfterCount\\((.+?)\\) must be a positive integer","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/window/trigger/trigger.go","lineNumber":84,"sourceCode":"}\n\n// String implements the Stringer interface and returns trigger details as a string.\nfunc (t *AfterCountTrigger) String() string {\n\treturn fmt.Sprintf(\"%#v\", t)\n}\n\nfunc (t AfterCountTrigger) trigger() {}\n\n// ElementCount returns the elementCount.\nfunc (t *AfterCountTrigger) ElementCount() int32 {\n\treturn t.elementCount\n}\n\n// AfterCount constructs a trigger that fires after\n// at least `count` number of elements are processed.\nfunc AfterCount(count int32) *AfterCountTrigger {\n\tif count < 1 {\n\t\tpanic(fmt.Errorf(\"trigger.AfterCount(%v) must be a positive integer\", count))\n\t}\n\treturn &AfterCountTrigger{elementCount: count}\n}\n\n// AfterProcessingTimeTrigger fires after passage of times defined in timestampTransforms.\ntype AfterProcessingTimeTrigger struct {\n\ttimestampTransforms []TimestampTransform\n}\n\n// String implements the Stringer interface and returns trigger details as a string.\nfunc (t *AfterProcessingTimeTrigger) String() string {\n\treturn fmt.Sprintf(\"%#v\", t)\n}\n\nfunc (t AfterProcessingTimeTrigger) trigger() {}\n\n// TimestampTransforms returns the timestampTransforms.\nfunc (t *AfterProcessingTimeTrigger) TimestampTransforms() []TimestampTransform {","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/window/trigger/trigger.go#L66-L102","documentation":"trigger.AfterCount builds a trigger that fires after at least `count` elements. It panics with this error when count is less than 1, since a non-positive element count is meaningless for an element-count trigger. It is a fail-fast constructor guard, not a recoverable pipeline error.","triggerScenarios":"Calling windowing.trigger.AfterCount(0) or AfterCount(-1) (e.g. count computed from a variable or config that defaulted to zero).","commonSituations":"Count loaded from an unset config/env variable defaulting to 0; off-by-one arithmetic producing 0; users assuming 0 means 'fire immediately'.","solutions":["Pass a positive integer >= 1 to AfterCount.","Clamp or validate the count variable before constructing the trigger.","If 'fire immediately' is intended, use trigger.AfterFirst() or a default trigger instead.","Check the config source feeding the count for missing/zero values."],"exampleFix":"// before\ntr := trigger.AfterCount(cfg.Count) // Count could be 0\n// after\nif cfg.Count < 1 { cfg.Count = 1 }\ntr := trigger.AfterCount(cfg.Count)","handlingStrategy":"validation","validationCode":"if count < 1 { return fmt.Errorf(\"AfterCount requires >= 1, got %d\", count) }","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        if strings.Contains(fmt.Sprint(r), \"AfterCount\") { return ErrInvalidTriggerCount }\n        panic(r)\n    }\n}()","preventionTips":["Validate config-sourced counts before constructing triggers","Remember AfterCount(0) is invalid; use AfterFirst() for immediate firing","Add tests covering zero/negative count inputs"],"tags":["go","apache-beam","trigger","panic","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}