wasmerio/wasmer · error
global #{} is a constant
Error message
global #{} is a constant What it means
During Wasm-to-Cranelift translation, code_translator handles Operator::GlobalSet. If state.get_global resolves the global index to GlobalVariable::Const, the global is a constant and cannot be assigned, so translation panics. Well-formed Wasm modules mark such globals immutable in their type section, so this usually indicates an invalid or corrupted module.
Source
Thrown at lib/compiler-cranelift/src/translator/code_translator.rs:231
GlobalVariable::Const(val) => val,
GlobalVariable::Memory { gv, offset, ty } => {
let addr =
materialize_global_value(&mut builder.cursor(), environ.pointer_type(), gv);
let mut flags = ir::MemFlagsData::trusted();
// Put globals in the "table" abstract heap category as well.
set_memflags_alias_region(builder.func, &mut flags, MemoryAliasRegion::Table);
builder.ins().load(ty, flags, addr, offset)
}
GlobalVariable::Custom => environ.translate_custom_global_get(
builder.cursor(),
GlobalIndex::from_u32(*global_index),
)?,
};
state.push1(val);
}
Operator::GlobalSet { global_index } => {
match state.get_global(builder.func, *global_index, environ)? {
GlobalVariable::Const(_) => panic!("global #{} is a constant", *global_index),
GlobalVariable::Memory { gv, offset, ty } => {
let addr =
materialize_global_value(&mut builder.cursor(), environ.pointer_type(), gv);
let mut flags = ir::MemFlagsData::trusted();
// Put globals in the "table" abstract heap category as well.
set_memflags_alias_region(builder.func, &mut flags, MemoryAliasRegion::Table);
let mut val = state.pop1();
// Ensure SIMD values are cast to their default Cranelift type, I8x16.
if ty.is_vector() {
val = optionally_bitcast_vector(val, I8X16, builder);
}
debug_assert_eq!(ty, builder.func.dfg.value_type(val));
builder.ins().store(flags, val, addr, offset);
}
GlobalVariable::Custom => {
let val = state.pop1();
environ.translate_custom_global_set(
builder.cursor(),View on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Validate the module before compilation (wasm-validate app.wasm or Wasmer's validation pass) — a valid module can never do this.
- Fix the producer toolchain so global.set only targets mutable (0x01 mutability) globals.
- Change the global's declared mutability byte in the module if it is genuinely meant to be written.
- If you believe the module is valid, report a Wasmer bug with the failing module attached.
Example fix
// before (globals section, byte view) 0x03 0x7F 0x00 0x41 0x00 0x0B // global #3, i32, MUTABLE=0x00 // after 0x03 0x7F 0x01 0x41 0x00 0x0B // global #3, i32, MUTABLE=0x01 (writable)
Defensive patterns
Strategy: validation
Validate before calling
// Validate modules before compiling; a valid module can never hit this: $ wasm-validate app.wasm # or via the wasm-tools/wasmparser validator in-pipeline
Try / catch
// Wrap compilation of untrusted modules
let result = std::panic::catch_unwind(|| compiler.compile(module, environ));
match result {
Ok(r) => r,
Err(_) => return Err(CompileError::InvalidModule("global.set on const global")),
} Prevention
- Run the Wasm validator on every untrusted or hand-built module before compilation.
- Ensure codegen tools emit global.set only for mutable globals.
- Fuzz your pipeline with the validator enabled to catch producer bugs.
When it happens
Trigger: Translating a function body (via parse_function_body → translate_operator) containing global.set whose index refers to a global recorded as Const — i.e. writing to an immutable global, typically from a module that bypassed validation or from a get_global/state tracking bug.
Common situations: Feeding hand-crafted or fuzzed Wasm binaries that skip the validator; toolchain bugs emitting global.set to immutable globals; old/hand-patched modules where the global's mutability flag disagrees with actual writes.
Related errors
- unimplemented operator {operator:?}
- cannot create debug directory: {}
- x86 support requires SSE2
- Unsupported libcall
- Unhandled inner case
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/0b2131b2d90a4062.
Report an issue: GitHub.