{"record":{"id":"3ff25f364ca93a27","repo":"vectordotdev/vector","slug":"linger-should-exists-for-poll-flush","errorCode":null,"errorMessage":"linger should exists for poll_flush","messagePattern":"linger should exists for poll_flush","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/sinks/util/sink.rs","lineNumber":298,"sourceCode":"\n    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {\n        loop {\n            // Poll inner service while not ready, if we don't have buffer or any batch.\n            if self.buffer.is_none() && self.partitions.is_empty() {\n                ready!(self.service.poll_complete(cx));\n                return Poll::Ready(Ok(()));\n            }\n\n            // Try send batches.\n            let this = self.as_mut().project();\n            let mut partitions_ready = vec![];\n            for (partition, batch) in this.partitions.iter() {\n                if ((*this.closing && !batch.is_empty())\n                    || batch.was_full()\n                    || matches!(\n                        this.lingers\n                            .get_mut(partition)\n                            .expect(\"linger should exists for poll_flush\")\n                            .poll_unpin(cx),\n                        Poll::Ready(())\n                    ))\n                    && this\n                        .in_flight\n                        .as_mut()\n                        .and_then(|map| map.get_mut(partition))\n                        .map(|req| matches!(req.poll_unpin(cx), Poll::Ready(())))\n                        .unwrap_or(true)\n                {\n                    partitions_ready.push(partition.clone());\n                }\n            }\n            let mut batch_consumed = false;\n            for partition in partitions_ready.iter() {\n                let service_ready = match this.service.poll_ready(cx) {\n                    Poll::Ready(Ok(())) => true,\n                    Poll::Ready(Err(error)) => return Poll::Ready(Err(error)),","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/sinks/util/sink.rs#L280-L316","documentation":"This panic fires in the partition batch sink's `poll_flush` when `lingers.get_mut(partition)` returns `None` for a partition that has an active batch. The sink maintains `partitions` and `lingers` maps in lockstep (every batched partition gets a linger timer), so a missing linger is an internal state inconsistency.","triggerScenarios":"Polling flush on a partitioned sink where the `partitions` map contains a key absent from `lingers` — e.g. a logic bug that inserts a batch without a corresponding linger, or removes a linger without removing the batch.","commonSituations":"Not reachable via configuration; appears only from bugs in partition lifecycle code or custom patches to src/sinks/util/sink.rs.","solutions":["Report as a bug to Vector with the sink type and scenario.","Check for recent patches to the partition batch sink that alter partitions/lingers bookkeeping.","Restart the topology to clear inconsistent in-memory state and confirm reproducibility."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep partitions and lingers insertion/removal in lockstep when patching sink.rs.","Restart the topology to clear inconsistent state after upgrades.","Report reproducible occurrences with the sink type and config."],"tags":["rust","partitioning","state-management","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}