{"record":{"id":"2d8c1c15087d0252","repo":"pola-rs/polars","slug":"itertools-zip-eq-reached-end-of-one-iterator-before-the","errorCode":null,"errorMessage":"itertools: .zip_eq() reached end of one iterator before the other","messagePattern":"itertools: \\.zip_eq\\(\\) reached end of one iterator before the other","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-utils/src/itertools/zip_eq.rs","lineNumber":20,"sourceCode":"\n/// An iterator which iterates two other iterators simultaneously\n/// and panic if they have different lengths.\n#[derive(Clone, Debug)]\n#[must_use = \"iterator adaptors are lazy and do nothing unless consumed\"]\npub struct ZipEq<I, J> {\n    a: I,\n    b: J,\n}\n\nimpl<I: Iterator, J: Iterator> Iterator for ZipEq<I, J> {\n    type Item = (I::Item, J::Item);\n\n    fn next(&mut self) -> Option<Self::Item> {\n        match (self.a.next(), self.b.next()) {\n            (None, None) => None,\n            (Some(a), Some(b)) => Some((a, b)),\n            (None, Some(_)) | (Some(_), None) => {\n                panic!(\"itertools: .zip_eq() reached end of one iterator before the other\")\n            },\n        }\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        let (a_lower, a_upper) = self.a.size_hint();\n        let (b_lower, b_upper) = self.b.size_hint();\n        let lower = cmp::min(a_lower, b_lower);\n        let upper = match (a_upper, b_upper) {\n            (Some(u1), Some(u2)) => Some(cmp::min(u1, u2)),\n            _ => a_upper.or(b_upper),\n        };\n        (lower, upper)\n    }\n}\n\nimpl<I: ExactSizeIterator, J: ExactSizeIterator> ExactSizeIterator for ZipEq<I, J> {}\n","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/crates/polars-utils/src/itertools/zip_eq.rs#L2-L38","documentation":"Polars' ZipEq iterator panics when one of the two zipped iterators is exhausted before the other, i.e. they have unequal lengths. Unlike std::iter::zip (which silently stops at the shorter iterator), zip_eq asserts both sides have equal length, since unequal lengths indicate a broken invariant in the calling code.","triggerScenarios":"Any use of zip_eq (from polars-utils' itertools) where the two iterators produce different numbers of elements — e.g. zipping columns of a frame that have different lengths, or chunk lists built inconsistently.","commonSituations":"Internal invariant bugs where two collections are assumed parallel but constructed differently; plugin/extension code zipping field lists against array lists after a schema change; version-skew between polars crates.","solutions":["Identify the two iterators being zipped and verify their lengths are equal before iteration","If unequal lengths are legitimate, use std::iter::zip instead of zip_eq and handle the short side","Report/fix the upstream invariant violation if this comes from within Polars itself (often a bug — check the issue tracker)"],"exampleFix":"// before\nassert_eq!(a.len(), b.len(), \"zip_eq inputs differ\");\nlet pairs: Vec<_> = a.iter().zip_eq(b.iter()).collect();\n// after\nif a.len() != b.len() {\n    let pairs: Vec<_> = a.iter().zip(b.iter()).collect(); // tolerate short side\n} else {\n    let pairs: Vec<_> = a.iter().zip_eq(b.iter()).collect();\n}","handlingStrategy":"type-guard","validationCode":"// Rust: assert equal lengths before zipping\nassert_eq!(a.len(), b.len(), \"zip_eq requires equal-length iterators\");","typeGuard":"fn equal_len<A, B>(a: &[A], b: &[B]) -> bool { a.len() == b.len() }","tryCatchPattern":null,"preventionTips":["Prefer std::iter::zip when unequal lengths are possible and tolerable","Check collection lengths at construction time, not iteration time","Keep polars crate versions in lockstep to avoid schema/chunk skew"],"tags":["rust","iterators","invariant","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}