wasmerio/wasmer · error
Can't form ExtraInfo with two pending canonicalization
Error message
Can't form ExtraInfo with two pending canonicalization
What it means
This panic occurs in `ExtraInfo`'s `bitand` implementation in wasmtime's LLVM backend state tracking. `ExtraInfo` can carry at most one pending NaN canonicalization flag (pending f32 or pending f64); when combining two infos that both have pending NaN flags, the `(true, true)` arm deliberately panics because the struct cannot represent two pending canonicalizations at once. It is an internal invariant violation in floating-point NaN legalization bookkeeping.
Source
Thrown at lib/compiler-llvm/src/translator/state.rs:213
debug_assert!(
self.has_pending_f64_nan() == other.has_pending_f64_nan()
|| self.is_arithmetic_f64()
|| other.is_arithmetic_f64()
);
let info = match (
self.is_arithmetic_f32() && other.is_arithmetic_f32(),
self.is_arithmetic_f64() && other.is_arithmetic_f64(),
) {
(false, false) => Default::default(),
(true, false) => ExtraInfo::arithmetic_f32(),
(false, true) => ExtraInfo::arithmetic_f64(),
(true, true) => (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
};
match (self.has_pending_f32_nan(), self.has_pending_f64_nan()) {
(false, false) => Ok(info),
(true, false) => info | ExtraInfo::pending_f32_nan(),
(false, true) => info | ExtraInfo::pending_f64_nan(),
(true, true) => unreachable!("Can't form ExtraInfo with two pending canonicalization"),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct TagCatchInfo<'ctx> {
pub tag: u32,
// The catch block
pub catch_block: BasicBlock<'ctx>,
// The PHI node to receive the exnref, if needed; catch_all
// blocks don't need the exnref.
pub exnref_phi: Option<PhiValue<'ctx>>,
}
#[derive(Debug)]
pub struct Landingpad<'ctx> {
// The block that has the landingpad instruction.
// Will be None for catch-less try_table instructionsView on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Upgrade wasmtime — NaN-canonicalization bookkeeping bugs are fixed over time
- Disable NaN canonicalization: `Config::wasm_nan_canonicalization(false)` (accepting non-deterministic NaNs) if your workload tolerates it
- Reduce the module with wasm-opt/NaN-transform passes so canonicalization is not needed at runtime
- Check whether a custom LLVM build changes float instruction selection and try the stock toolchain
- Report with a minimal f32/f64 module reproducing the double pending canonicalization
Example fix
// before let mut config = Config::default(); config.wasm_nan_canonicalization(true); // after let mut config = Config::default(); config.wasm_nan_canonicalization(false); // avoid the ExtraInfo invariant panic
Defensive patterns
Strategy: validation
Validate before calling
let mut config = wasmtime::Config::default(); config.wasm_nan_canonicalization(false); // skip the ExtraInfo NaN bookkeeping entirely if your workload tolerates it let engine = Engine::new(&config)?;
Try / catch
let module = std::panic::catch_unwind(|| Module::new(&engine, &bytes).map_err(|e| anyhow::anyhow!(e)))
.map_err(|_| anyhow::anyhow!("compiler panic"))??;
// on panic: retry with wasm_nan_canonicalization(false) Prevention
- If determinism is not required, leave wasm_nan_canonicalization disabled on older wasmtime
- Upgrade wasmtime promptly; NaN bookkeeping fixes land regularly
- Combine f32/f64-heavy modules under CI compile tests when enabling canonicalization
- Compile modules off-thread so panics don't abort the host
When it happens
Trigger: Chaining floating-point LLVM operations (via `and` on `ExtraInfo`) where both operands produced a pending NaN canonicalization — e.g. `ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64()` combined with state that already has both `has_pending_f32_nan()` and `has_pending_f64_nan()` set.
Common situations: Running wasm with unusual NaN-heavy float code through the LLVM backend; enabling `wasm_nan_canonicalization` (or backends where it is default) on versions with bookkeeping bugs; modules mixing f32/f64 NaN-producing ops in patterns the tracker didn't expect.
Related errors
- duplicate function
- Unhandled internal variant
- internal error: entered unreachable code
- Symbol {} in DWARF not recognized
- internal error: entered unreachable code
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/605c09d4ef657031.
Report an issue: GitHub.