{"record":{"id":"ae979dc0139c284f","repo":"astral-sh/ruff","slug":"expected-live-declarations-length-to-fit-into-a-u3","errorCode":null,"errorMessage":"Expected live-declarations length to fit into a u32","messagePattern":"Expected live-declarations length to fit into a u32","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ty_python_core/src/use_def.rs","lineNumber":557,"sourceCode":"}\n\nstruct RetainedDeclarationsBuilder {\n    ends: IndexVec<InternedDeclarationsId, u32>,\n    live_declarations: Vec<LiveDeclaration>,\n}\n\nimpl RetainedDeclarationsBuilder {\n    fn with_capacity(declarations: usize) -> Self {\n        Self {\n            ends: IndexVec::with_capacity(declarations),\n            live_declarations: Vec::with_capacity(declarations),\n        }\n    }\n\n    fn push(&mut self, declarations: &Declarations) -> InternedDeclarationsId {\n        self.live_declarations.extend(declarations.iter().cloned());\n        let end = u32::try_from(self.live_declarations.len())\n            .expect(\"Expected live-declarations length to fit into a u32\");\n        self.ends.push(end)\n    }\n\n    fn finish(\n        self,\n        reachability_constraints: &mut ReachabilityConstraintsBuilder,\n    ) -> RetainedDeclarations {\n        for declaration in &self.live_declarations {\n            reachability_constraints.mark_used(declaration.reachability_constraint);\n        }\n        RetainedDeclarations {\n            ends: self.ends.into(),\n            live_declarations: self.live_declarations.into_boxed_slice(),\n        }\n    }\n}\n\nimpl Index<InternedDeclarationsId> for RetainedDeclarations {","sourceCodeStart":539,"sourceCodeEnd":575,"githubUrl":"https://github.com/astral-sh/ruff/blob/15f3fe6b15a5f00172f34b0f542f8ea277f5a586/crates/ty_python_core/src/use_def.rs#L539-L575","documentation":"RetainedDeclarationsBuilder flattens every scope's live use-def declarations into one Vec and records each scope's end offset as a u32, the index type used to address RetainedDeclarations. The expect fires when the cumulative live-declaration count pushed into a single UseDefMap exceeds u32::MAX (4,294,967,295) and can no longer be represented as an end offset. This is a capacity invariant of the compact interning scheme, not a configurable limit; a normal process would exhaust memory long before reaching it.","triggerScenarios":"Building the use-def map for a module whose total live declarations, summed across every scope and place that gets interned, crosses 4,294,967,295. Only astronomically large or adversarially generated input can approach it, or a runaway interning loop that duplicates declarations per scope.","commonSituations":"Machine-generated multi-gigabyte Python modules; fuzzing harnesses that synthesize huge numbers of scopes; in practice, hitting this panic almost always indicates a bug that duplicates declarations rather than a legitimately large file, because out-of-memory occurs first.","solutions":["Split the oversized module into several files so each use-def map stays far below billions of declarations","If the file is not abnormally large, capture it and file a ty issue: the panic signals a runaway declaration-interning loop (the same declarations interned repeatedly)","As a contributor, if legitimate inputs could ever exceed u32::MAX, widen the end offsets to u64 or chunk the retained vectors rather than unwrapping the conversion"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| check_file(&db, file)));\nmatch result {\n    Ok(diags) => diags,\n    Err(payload) => { log::warn!(\"ty panicked on {}: {:?}\", file, payload); vec![] }\n}","preventionTips":["Split machine-generated mega-modules so single-file use-def maps stay small","If you embed ty, isolate per-file checking with catch_unwind so one pathological file does not kill the run","Treat this panic as a canary: a normal-sized file hitting it means an interning loop bug - report it"],"tags":["rust","ty","use-def","panic","integer-overflow","internal-invariant"],"backgroundTag":"integer-conversion-overflow","analyzedSha":"15f3fe6b15a5f00172f34b0f542f8ea277f5a586","analyzedAt":"2026-08-20T16:33:49.445Z","contentChangedAt":"2026-08-20T16:33:49.445Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}