{"record":{"id":"99ddb3887f04d447","repo":"seanmonstar/warp","slug":"polled-after-complete","errorCode":null,"errorMessage":"polled after complete","messagePattern":"polled after complete","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/filter/and.rs","lineNumber":93,"sourceCode":"    U::Error: CombineRejection<E>,\n{\n    type Output = Result<CombinedTuples<TE, U::Extract>, <U::Error as CombineRejection<E>>::One>;\n\n    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {\n        loop {\n            match self.as_mut().project() {\n                StateProj::First(first, second) => {\n                    let ex1 = ready!(first.poll(cx))?;\n                    let fut2 = second.filter(Internal);\n                    self.set(State::Second(Some(ex1), fut2));\n                }\n                StateProj::Second(ex1, second) => {\n                    let ex2 = ready!(second.poll(cx))?;\n                    let ex3 = ex1.take().unwrap().combine(ex2);\n                    self.set(State::Done);\n                    return Poll::Ready(Ok(ex3));\n                }\n                StateProj::Done => panic!(\"polled after complete\"),\n            }\n        }\n    }\n}\n","sourceCodeStart":75,"sourceCodeEnd":98,"githubUrl":"https://github.com/seanmonstar/warp/blob/ff34d7213ed55ec342304aa7ff6ac4b351da9e66/src/filter/and.rs#L75-L98","documentation":"This is an internal invariant panic from the `And` filter's combinator future. The future transitions to `State::Done` after both inner futures complete, and polling it afterwards is a protocol violation by the executor: futures must not be polled after returning `Poll::Ready`. The library panics instead of returning a value because there is no valid result to produce.","triggerScenarios":"Polling the `And` combinator future (`StateProj::Done` branch in `poll`) a second time after it already returned `Poll::Ready(Ok(ex3))` — e.g. a buggy custom executor, wrapping the future in a combinator that re-polls, or storing the future and calling `poll` again after completion.","commonSituations":"Custom tokio executors that double-poll, home-grown `Future` wrappers (e.g. fused logic implemented incorrectly), task spawning frameworks that poll after `Ready`, or misuse of the raw future type instead of `.await` / `Pending`.","solutions":["Use standard `.await` or `tokio::spawn` to drive the future instead of manually calling `poll()`.","If manual polling is required, stop polling once `Poll::Ready` is returned, or wrap the future in `futures::future::Fuse` (or a `FusedFuture` guard) so it is never re-polled.","Audit any custom executor or wrapper for the invariant: after `Poll::Ready`, drop the future or never call `poll` again.","Check for shared/aliased use of the same future from two tasks, which can lead to a post-completion poll."],"exampleFix":"// before\nlet mut fut = filter.and(other_filter);\nlet out1 = Pin::new(&mut fut).poll(cx);\nlet out2 = Pin::new(&mut fut).poll(cx); // panic: polled after complete\n\n// after\nlet out = filter.and(other_filter).await; // drive via async/await\n// or with manual polling:\nif !fut.is_terminated() {\n    let out = Pin::new(&mut fut).poll(cx);\n}","handlingStrategy":"try-catch","validationCode":"use futures::future::FusedFuture;\nfn safe_to_poll<F: FusedFuture>(fut: &F) -> bool { !fut.is_terminated() }","typeGuard":"fn is_pollable(fut: &dyn FusedFuture) -> bool { !fut.is_terminated() }","tryCatchPattern":"// Panics cannot be caught normally; drive via await so it never occurs:\nasync { filter.and(other).await } // executor guarantees single poll to completion","preventionTips":["Never call `poll` manually; use async/await or a runtime spawn.","Wrap manually-polled futures in `futures::future::Fuse` and check `is_terminated()`.","Break polling loops immediately on `Poll::Ready`.","Ensure one owner polls each future instance."],"tags":["panic","future","internal-invariant","rust","poll"],"backgroundTag":"invalid-state-transition","analyzedSha":"ff34d7213ed55ec342304aa7ff6ac4b351da9e66","analyzedAt":"2026-09-09T16:57:46.316Z","contentChangedAt":"2026-09-09T16:57:46.316Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}