{"record":{"id":"c4e62e6d59db008d","repo":"linera-io/linera-protocol","slug":"invalid-i32-stored-in-i64","errorCode":null,"errorMessage":"Invalid `i32` stored in `i64`","messagePattern":"Invalid `i32` stored in `i64`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-witty/src/primitive_types/flat_type.rs","lineNumber":65,"sourceCode":"    fn split_from_f64(joined_f64: f64) -> Self;\n\n    /// Splits off the `Target` flat type from this flat type.\n    ///\n    /// # Panics\n    ///\n    /// If the `Target` type can't be joined into this flat type.\n    fn split_into<Target: FlatType>(self) -> Target;\n}\n\nimpl FlatType for i32 {\n    fn split_from_i32(joined_i32: i32) -> Self {\n        joined_i32\n    }\n\n    fn split_from_i64(joined_i64: i64) -> Self {\n        joined_i64\n            .try_into()\n            .expect(\"Invalid `i32` stored in `i64`\")\n    }\n\n    fn split_from_f32(_joined_f32: f32) -> Self {\n        unreachable!(\"`i32` is never joined into `f32`\");\n    }\n\n    fn split_from_f64(_joined_f64: f64) -> Self {\n        unreachable!(\"`i32` is never joined into `f64`\");\n    }\n\n    fn split_into<Target: FlatType>(self) -> Target {\n        Target::split_from_i32(self)\n    }\n}\n\nimpl FlatType for i64 {\n    fn split_from_i32(_joined_i32: i32) -> Self {\n        unreachable!(\"`i64` is never joined into `i32`\");","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-witty/src/primitive_types/flat_type.rs#L47-L83","documentation":"linera-witty maps WIT primitive types onto WebAssembly flat types per the Component Model canonical ABI. When a value was 'joined' into an i64 flat slot (e.g. flattening a variant whose cases have different widths) and must be split back into an i32-backed type, `i64::try_into::<i32>()` fails for values outside [-2^31, 2^31-1]. The panic means the guest returned a flat value that does not fit the declared WIT type — a guest-side ABI contract violation, not normal control flow.","triggerScenarios":"A guest function whose result unflattens through an i64-to-i32 split returns a value such as 3_000_000_000; guest and host compiled from different WIT interfaces, so an i64-wide value is read where an i32-backed type (u32/s32/char) is declared.","commonSituations":"A WIT type changed from u32 to u64 (or vice versa) and only one side regenerated; a guest computing in i64 and returning across the boundary without a range check; fuzzing guests with unchecked arithmetic.","solutions":["Range-check in the guest before returning any i32-backed WIT type (u32/s32/char/bool): return an error variant instead of an out-of-range value","Regenerate and rebuild guest and host from the same WIT package version so the flat layouts match","If values legitimately exceed i32, change the WIT type to u64/s64 and regenerate both sides","Add a boundary unit test asserting every returned value fits its declared WIT type"],"exampleFix":"// before (guest): computes in i64, returns unchecked across the WIT boundary\nfn score(delta: u64) -> u32 { big_computation(delta) as u32 } // joined i64 > i32::MAX -> host panics on split\n\n// after (guest): validate at the boundary\nfn score(delta: u64) -> Result<u32, Error> {\n    let v = big_computation(delta);\n    u32::try_from(v).map_err(|_| Error::Overflow)\n}","handlingStrategy":"type-guard","validationCode":"// guest: guard every i32-backed return before crossing the WIT boundary\nlet v: i64 = compute();\nassert!(i32::try_from(v).is_ok(), \"value {v} overflows the declared WIT type\");","typeGuard":"fn fits_i32(v: i64) -> bool { i32::try_from(v).is_ok() }","tryCatchPattern":null,"preventionTips":["Regenerate host and guest bindings together whenever the WIT interface changes","Keep integer widths identical (WIT u32 <-> Rust u32) on both sides of the boundary","Never cast wide-to-narrow at the boundary without try_from"],"tags":["wasm","wit","component-model","type-conversion","linera-witty"],"backgroundTag":"wasm-abi-type-mismatch","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}