{"record":{"id":"9b14704a6be20dde","repo":"apache/beam","slug":"prism-consistency-error-trying-to-remove-a-timer-for-a-key","errorCode":null,"errorMessage":"prism consistency error: trying to remove a timer for a key without timers: %v,%+v","messagePattern":"prism consistency error: trying to remove a timer for a key without timers: (.+?),%\\+v","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/runners/prism/internal/engine/timers.go","lineNumber":325,"sourceCode":"\t\t\treturn map[timerKey]fireElement{}\n\t\t}},\n\t}\n}\n\n// timers returns the timers for the userkey.\nfunc (th *timerHandler) timers(timer element) map[timerKey]fireElement {\n\ttimers, ok := th.nextFiring[string(timer.keyBytes)]\n\tif !ok {\n\t\ttimers = th.firingMapPool.Get().(map[timerKey]fireElement)\n\t\tth.nextFiring[string(timer.keyBytes)] = timers\n\t}\n\treturn timers\n}\n\nfunc (th *timerHandler) removeTimer(userKey string, key timerKey) element {\n\ttimers, ok := th.nextFiring[userKey]\n\tif !ok {\n\t\tpanic(fmt.Sprintf(\"prism consistency error: trying to remove a timer for a key without timers: %v,%+v\", userKey, key))\n\t}\n\ttimes, ok := timers[key]\n\tif !ok {\n\t\tpanic(fmt.Sprintf(\"prism consistency error: trying to remove a non-existent timer for a key: %v,%+v\", userKey, key))\n\t}\n\tdelete(timers, key)\n\tif len(timers) == 0 {\n\t\tdelete(th.nextFiring, userKey)\n\t\tth.firingMapPool.Put(timers)\n\t}\n\treturn times.timer\n}\n\nfunc (th *timerHandler) add(key timerKey, newFire fireElement) {\n\tbyKeys, ok := th.toFire[newFire.firing]\n\tif !ok {\n\t\tbyKeys = th.userKeysSetPool.Get().(map[string]set[timerKey])\n\t\tth.toFire[newFire.firing] = byKeys","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/runners/prism/internal/engine/timers.go#L307-L343","documentation":"timerHandler.removeTimer expects an entry in nextFiring for the given user key before deleting a timer. When no timer map exists for that key, prism's internal timer bookkeeping is inconsistent, so it panics with this consistency error. This indicates a runner-side bug or a malformed timer protocol interaction rather than user data corruption.","triggerScenarios":"FireAt processing a firing request references a timer for a user key that was never registered in nextFiring, e.g. duplicate fire callbacks, timers cleared twice, or a test-stream replay referencing an already-removed timer.","commonSituations":"Running pipelines with timers on prism while retrying bundles, replaying TestStream contents, or hitting races between timer clearing and firing during job teardown.","solutions":["Update to the latest Beam version; this class of prism consistency panic is usually fixed in newer releases.","Check for duplicate timer firings for the same key/timestamp in the pipeline (e.g. re-setting timers inside timers).","Capture the job graph and file a bug with the Beam project including the pipeline and stage that panicked.","As a workaround, avoid clearing timers from within the same bundle that fires them."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before firing, verify the timer is registered\nif _, ok := handler.HasTimer(userKey, timerKey); !ok {\n    log.Printf(\"timer %v for key %v not registered; skipping fire\", timerKey, userKey)\n}","typeGuard":null,"tryCatchPattern":"func safeFire(h *timerHandler, userKey string, key timerKey) (recovered any) {\n    defer func() { recovered = recover() }()\n    h.FireAt(userKey, key)\n    return nil\n}","preventionTips":["Avoid setting and clearing the same timer within one bundle","Upgrade Beam to get timer-handling fixes","Report panics with a reproducing TestStream script"],"tags":["go","panic","timer","internal-state","beam-prism"],"backgroundTag":"internal-invariant-violation","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"}