{"record":{"id":"e05e7f3dcf77fda0","repo":"astral-sh/ruff","slug":"bindings-must-not-be-empty","errorCode":null,"errorMessage":"bindings must not be empty","messagePattern":"bindings must not be empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ty_python_semantic/src/types/call/bind.rs","lineNumber":749,"sourceCode":"        &mut self,\n        db: &'db dyn Db,\n        generic_context: GenericContext<'db>,\n    ) {\n        for element in &mut self.elements {\n            for item in &mut element.items {\n                match item {\n                    CallableItem::Regular(binding) => {\n                        for overload in &mut binding.overloads {\n                            overload.signature.generic_context = GenericContext::merge_optional(\n                                db,\n                                overload.signature.generic_context,\n                                Some(generic_context),\n                            );\n                        }\n                    }\n                    CallableItem::Constructor(binding) => {\n                        for overload in &mut binding.entry.overloads {\n                            overload.signature.generic_context = GenericContext::merge_optional(\n                                db,\n                                overload.signature.generic_context,\n                                Some(generic_context),\n                            );\n                        }\n                        if let Some(downstream) = binding.downstream_constructor_mut() {\n                            downstream.apply_generic_context_in_place(db, generic_context);\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    /// Creates a new `Bindings` from an iterator of [`Bindings`]s for a union type.\n    /// Each input `Bindings` becomes a union element, preserving any intersection structure.\n    /// Panics if the iterator is empty.\n    pub(crate) fn from_union<I>(callable_type: Type<'db>, bindings_iter: I) -> Self","sourceCodeStart":731,"sourceCodeEnd":767,"githubUrl":"https://github.com/astral-sh/ruff/blob/15f3fe6b15a5f00172f34b0f542f8ea277f5a586/crates/ty_python_semantic/src/types/call/bind.rs#L731-L767","documentation":"Bindings::from_union merges the per-element bindings of a union of callables into one value, using the first element as the accumulator for the shared elements buffer. The expect fires when the iterator is empty: from_union requires at least one Bindings to merge.","triggerScenarios":"Calling from_union with an empty iterator - e.g., invoking a value whose callable-union elements all got filtered out before binding, or an empty union (Never-adjacent) reaching the call path.","commonSituations":"Empty-union edge cases in call inference; refactors of union-call handling where filtering can now remove every branch before from_union runs.","solutions":["Handle the empty case at the call site: return a not-callable/unbound binding instead of calling from_union with no elements","File a ty issue with the call expression (Never-typed callables and empty unions are the usual triggers)","As a contributor: encode the non-empty requirement in the signature (take head plus tail, or return Option) instead of unwrapping next()"],"exampleFix":"// before\nlet merged = Bindings::from_union(callable_type, bindings_iter);\n\n// after\nlet mut bindings_iter = bindings_iter.into_iter();\nlet Some(first) = bindings_iter.next() else {\n    return Bindings::empty(callable_type);\n};\nlet merged = Bindings::from_union(callable_type, once(first).chain(bindings_iter));","handlingStrategy":"validation","validationCode":"let mut iter = bindings_iter.into_iter();\nif let Some(first) = iter.next() {\n    Bindings::from_union(callable_type, std::iter::once(first).chain(iter));\n} else {\n    // no callable elements to merge: produce a not-callable result instead of merging","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check for at least one element before merging bindings of a union","When filtering callable-union elements before a call, keep an explicit empty-case branch","Encode non-emptiness in APIs (head + tail) instead of relying on unwrap of next()"],"tags":["rust","ty","call-inference","union","empty-iterator","panic"],"backgroundTag":"empty-iterator-next","analyzedSha":"15f3fe6b15a5f00172f34b0f542f8ea277f5a586","analyzedAt":"2026-08-20T16:33:49.445Z","contentChangedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}