{"record":{"id":"af01478e9aa1fe0d","repo":"rayon-rs/rayon","slug":"unzip-consumers-didn-t-execute","errorCode":null,"errorMessage":"unzip consumers didn't execute!","messagePattern":"unzip consumers didn't execute!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/iter/unzip.rs","lineNumber":225,"sourceCode":"    fn drive_unindexed<C>(self, consumer: C) -> C::Result\n    where\n        C: UnindexedConsumer<Self::Item>,\n    {\n        let mut result = None;\n        {\n            // Now it's time to find the consumer for type `B`\n            let iter = UnzipB {\n                base: self.base,\n                op: self.op,\n                left_consumer: consumer,\n                left_result: &mut result,\n            };\n            self.b.par_extend(iter);\n        }\n        // NB: If for some reason `b.par_extend` doesn't actually drive the\n        // iterator, then we won't have a result for the left side to return\n        // at all.  We can't fake an arbitrary consumer's result, so panic.\n        result.expect(\"unzip consumers didn't execute!\")\n    }\n\n    fn opt_len(&self) -> Option<usize> {\n        if OP::indexable() {\n            self.base.opt_len()\n        } else {\n            None\n        }\n    }\n}\n\n/// A fake iterator to intercept the `Consumer` for type `B`.\nstruct UnzipB<'r, I, OP, CA>\nwhere\n    I: ParallelIterator,\n    OP: UnzipOp<I::Item>,\n    CA: UnindexedConsumer<OP::Left>,\n{","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/rayon-rs/rayon/blob/ee0a00bdb1ab039e178a215ad5712fb7fa58e58f/src/iter/unzip.rs#L207-L243","documentation":"`UnzipConsumer::drive_unindexed` returns the left consumer's result via `Option::expect`; it panics if the right side's `par_extend` never drove the iterator, leaving no result for the left. This indicates the unzip consumer protocol was violated internally.","triggerScenarios":"Unzipping an unindexed parallel iterator where the right consumer's `par_extend` fails to actually consume the items (internal consumer contract violation), so `result` remains None.","commonSituations":"Rare; arises from rayon bugs or custom `Consumer` implementations used with `unzip` that don't drive the fed iterator.","solutions":["Upgrade rayon to the latest version","If using a custom Consumer/UnindexedConsumer impl, ensure it drives all fed items in `par_extend`","Work around by splitting the iterator: `let (a, b): (Vec<_>, Vec<_>) = iter.map(|x| (f(x), g(x))).unzip();` with collected intermediates","File a minimal repro on the rayon issue tracker"],"exampleFix":"// before\ncustom_unzip_consumer_drive(iter); // protocol-violating consumer\n// after\nlet (left, right): (Vec<_>, Vec<_>) = iter.unzip();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let r = catch_unwind(AssertUnwindSafe(|| iter.unzip()));\nif r.is_err() { /* fall back to sequential unzip */ }","preventionTips":["Use stock rayon consumers, not custom ones, with unzip","Upgrade rayon when hitting consumer-contract panics","Add a sequential unzip fallback path"],"tags":["rayon","panic","unzip","invariant-violation"],"backgroundTag":"internal-invariant-violation","analyzedSha":"ee0a00bdb1ab039e178a215ad5712fb7fa58e58f","analyzedAt":"2026-09-07T23:28:47.588Z","contentChangedAt":"2026-09-07T23:28:47.588Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}