{"record":{"id":"bf61a554ad191711","repo":"BoundaryML/baml","slug":"enum-offset-fits-u32","errorCode":null,"errorMessage":"enum offset fits u32","messagePattern":"enum offset fits u32","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"baml_language/crates/baml_compiler2_emit/src/lib.rs","lineNumber":2440,"sourceCode":"            }\n        })\n        .collect();\n    // Per pool object: its LocalRef within its owning unit (bucket + offset).\n    let mut obj_localref: Vec<LocalRef> = Vec::with_capacity(tail_start - prefix_objects);\n    for (offset, kind) in obj_kind.iter().enumerate() {\n        let idx = prefix_objects + offset;\n        let u = obj_owner[idx];\n        let obj = program.objects[ObjectIndex::from_raw(idx)].clone();\n        let local_ref = match kind {\n            PoolObjKind::Class => {\n                let off = units[u].classes.len();\n                units[u].classes.push(obj);\n                LocalRef::Class(u32::try_from(off).expect(\"class offset fits u32\"))\n            }\n            PoolObjKind::Enum => {\n                let off = units[u].enums.len();\n                units[u].enums.push(obj);\n                LocalRef::Enum(u32::try_from(off).expect(\"enum offset fits u32\"))\n            }\n            PoolObjKind::Interface => {\n                let off = units[u].interfaces.len();\n                units[u].interfaces.push(obj);\n                LocalRef::Interface(u32::try_from(off).expect(\"interface offset fits u32\"))\n            }\n            PoolObjKind::TypeAlias => {\n                let off = units[u].type_alias_objects.len();\n                units[u].type_alias_objects.push(obj);\n                LocalRef::TypeAlias(u32::try_from(off).expect(\"type-alias offset fits u32\"))\n            }\n            PoolObjKind::NamedFn(_) | PoolObjKind::CodeAnon => {\n                let off = units[u].code.len();\n                units[u].code.push(obj);\n                LocalRef::Code(u32::try_from(off).expect(\"code offset fits u32\"))\n            }\n        };\n        obj_localref.push(local_ref);","sourceCodeStart":2422,"sourceCodeEnd":2458,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/baml_compiler2_emit/src/lib.rs#L2422-L2458","documentation":"A Rust `expect(\"enum offset fits u32\")` panic in baml_compiler2_emit's local-unit packing code. While distributing pooled enum objects into per-unit local pools, the next enum offset (`units[u].enums.len()`) is converted to `u32`; the compiler assumes each unit holds fewer than 2^32 enums. Exceeding that indicates runaway or duplicated pooling, so the library panics instead of truncating offsets.","triggerScenarios":"Triggered while assigning `PoolObjKind::Enum` objects to local units when `units[u].enums.len()` exceeds `u32::MAX` — only reachable with an absurdly large or pathologically duplicated enum pool.","commonSituations":"Not hit by real BAML programs; appears in fuzzing or compiler-dev contexts such as a dedup failure pushing enums repeatedly, or synthetic inputs with billions of enum declarations.","solutions":["Audit the pooling loop for duplicate assignment of the same enum object to a unit (dedup key bug).","Add an explicit capacity check that emits a proper compile diagnostic before exceeding u32 capacity.","Widen the offset storage to `u64`/`usize` in `LocalRef` and serialized unit format if huge inputs must be supported.","Inspect the input program's enum count; a legitimate program cannot approach 2^32 enums."],"exampleFix":"// before\nlet off = units[u].enums.len();\nunits[u].enums.push(obj);\nLocalRef::Enum(u32::try_from(off).expect(\"enum offset fits u32\"))\n// after\nif units[u].enums.len() > u32::MAX as usize {\n    return Err(EmitError::UnitOverflow { unit: u, kind: \"enum\" });\n}\nlet off = units[u].enums.len();\nunits[u].enums.push(obj);\nLocalRef::Enum(off as u32)","handlingStrategy":"validation","validationCode":"// Not applicable to BAML users. Embedders can pre-check pool size before packing:\nfn enum_pool_within_u32(program: &Program) -> bool {\n    program.objects.iter().filter(|o| matches!(o, Object::Enum(_))).count() < u32::MAX as usize\n}","typeGuard":null,"tryCatchPattern":"// Panics are not catchable from BAML user code. Embedders can isolate compilation:\nlet result = std::panic::catch_unwind(|| compile(&source));\nif result.is_err() {\n    report_internal_compiler_error();\n}","preventionTips":["Keep per-unit enum counts below 2^32 by construction (real programs never approach this).","Deduplicate pooled enums so each object is pushed to a unit at most once.","Add a compile-time capacity check with a clear diagnostic instead of `expect`.","Fuzz with synthetic large inputs to catch overflow paths early."],"tags":["compiler","overflow","panic","rust"],"backgroundTag":"value-out-of-range","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}