wasmerio/wasmer · critical

Failed to load newly built in-memory module: {e}

Error message

Failed to load newly built in-memory module: {e}

What it means

closure_prepare builds a WASM module in memory (build_closure_wasm_bytes) and immediately loads it through the instance linker. If that freshly generated module fails to validate or instantiate, the code panics with "Failed to load newly built in-memory module", on the assumption the generated bytes are always valid. This indicates a bug in the generator or an incompatible loader, not user data corruption.

Source

Thrown at lib/wasix/src/syscalls/wasix/closure_prepare.rs:387

    let wasm_bytes = build_closure_wasm_bytes(
        &module_name,
        closure,
        backing_function,
        environment.offset().into(),
        &argument_types,
        &result_types,
    );

    let ld_library_path: [&Path; 0] = [];
    let wasm_loader = DlModuleSpec::Memory {
        module_name: &module_name,
        bytes: &wasm_bytes,
    };
    let module_handle = match linker.load_module(wasm_loader, &mut ctx) {
        Ok(m) => m,
        Err(e) => {
            // Should never happen
            panic!("Failed to load newly built in-memory module: {e}");
        }
    };

    return Ok(Errno::Success);
}

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Inspect the wrapped error `e` in the panic message to identify the validation failure (e.g. unsupported opcode).
  2. Remove V128 types from the closure signature if the runtime/engine lacks SIMD support.
  3. Upgrade or align wasmer/wasix versions so the dylink.0 module loader matches the generator.
  4. File a bug with the panic's inner error; this path is documented as 'should never happen'.

Example fix

// before
let signature_with_v128 = &[ValType::V128];
// after
let signature = &[ValType::I32]; // avoid V128 when engine lacks SIMD
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the engine supports SIMD before using v128 in closure signatures
assert!(engine.features().simd(), "SIMD required for v128 closure params");

Try / catch

// Around the syscall boundary, catch the resulting process abort in tests:
let result = std::panic::catch_unwind(|| closure_prepare(...));
if result.is_err() { /* regenerate closure or fall back to manual trampoline */ }

Prevention

When it happens

Trigger: Invoking the closure_prepare syscall; linker.load_module rejects the just-built module bytes (validation error, unsupported feature like V128 without SIMD enabled, dylink.0 handling failure, or loader mismatch).

Common situations: Runtime compiled without SIMD support while closure signatures include V128; wasmer version mismatch where the generated dylink.0 section is not accepted; internal generator bug producing malformed WASM.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/c796525c2c7bc4cc. Report an issue: GitHub.