How to Fix: `wasmtime run GC=no` doesn’t seem to disable GC in the host
GC=no looks like it should turn off garbage collection everywhere, but in Wasmtime it only affects the WebAssembly configuration path that reads that setting. The host process can still initialize and use GC-related runtime behavior, which makes the flag appear broken when you launch with wasmtime run.
Understanding the Root Cause
The issue comes from a mismatch between what GC=no seems to promise and what it actually controls. In this case, the environment variable does not act as a global host-level kill switch. Instead, it influences the Wasm execution configuration used by wasmtime run when enabling or disabling features related to the WebAssembly GC proposal.
That distinction matters because Wasmtime has multiple layers:
- The CLI layer, which parses arguments and environment settings.
- The engine/configuration layer, which decides whether Wasm GC features are enabled for compiled modules.
- The host runtime layer, which may still allocate, manage references, or initialize GC-capable internals regardless of that environment variable.
So if you observe host-side behavior that still looks like GC is active, that does not necessarily mean the CLI ignored your setting. More often, it means GC=no disables a guest feature flag, not the entire host runtime machinery.
In practice, this bug report usually surfaces when users expect one of these behaviors:
GC=no wasmtime run module.wasmshould prevent all GC-related code paths.- The host should reject any GC-capable runtime setup.
- The runtime should behave as if GC support was never compiled in.
Those expectations are stronger than the current implementation. The host can still be built with GC support, and internal runtime behavior may still exist even when Wasm GC is disabled for the loaded module.
Step-by-Step Solution
The fix is to stop relying on GC=no as a host-wide control and instead verify and enforce GC behavior through the actual Wasmtime configuration surface.
Step 1: Reproduce the behavior clearly
GC=no wasmtime run your-module.wasm
If the module still appears to interact with GC-related host functionality, confirm whether you are testing guest Wasm GC support or host runtime internals. These are not the same thing.
Step 2: Validate whether the module requires Wasm GC
If the module was compiled with the WebAssembly GC proposal, disabling GC support at the engine level should typically make validation or compilation fail.
wasmtime run your-gc-module.wasm
Then compare with:
GC=no wasmtime run your-gc-module.wasm
If both succeed, the important question is whether GC=no is wired to the code path you are using in your Wasmtime version.
Step 3: Prefer explicit CLI or engine configuration over ambient environment flags
When debugging or fixing this in source, look for where Wasmtime constructs its Config and whether the GC-related option is applied there. The real fix is usually one of these:
- Map
GC=noto the exact engine configuration that disables Wasm GC. - Document that the flag only affects proposal enablement, not host internals.
- Reject misleading behavior by surfacing a clear error when users expect host-wide GC shutdown.
Step 4: Patch the host setup if you are fixing the bug in Wasmtime itself
In the CLI or runtime setup code, ensure the environment setting is translated into the same config path used by explicit feature toggles.
let mut config = wasmtime::Config::new();
config.wasm_gc(false);
let engine = wasmtime::Engine::new(&config)?;
If the current implementation reads GC=no but does not call the equivalent of config.wasm_gc(false) for the active engine instance, the flag will not have the expected effect.
Step 5: Verify the fix with a module that truly depends on Wasm GC
# Expected to work when GC is enabled
wasmtime run gc-dependent-module.wasm
# Expected to fail or reject the module when GC is disabled
GC=no wasmtime run gc-dependent-module.wasm
A good fix should make the second command fail in a predictable way if the module requires GC-specific features.
Step 6: Update docs or release notes
If the issue is partly semantic, document the scope of GC=no precisely. A strong wording is: disables Wasm GC proposal support for module compilation and execution, but does not disable general host-side runtime memory management behavior.
Common Edge Cases
- Version mismatch: older and newer Wasmtime releases may differ in how feature flags are parsed or applied.
- Wrong test artifact: a module without GC-specific constructs may run identically whether GC is enabled or disabled, creating a false negative.
- Precompiled artifacts: if you use cached or precompiled modules, you may not be exercising the current engine configuration at all.
- Embedded Wasmtime hosts: if you are not using the CLI directly, your application may create its own
Configand ignore environment expectations entirely. - Host allocation confusion: normal Rust or runtime allocations inside the host are not proof that the Wasm GC feature is still enabled.
FAQ
Does GC=no disable all garbage collection in Wasmtime?
No. It should be treated as a feature toggle for WebAssembly GC support, not as a universal shutdown for every host-side memory management path.
Why does my module still run with GC=no?
Either the module does not actually require Wasm GC features, or your Wasmtime version does not apply that setting to the engine path you are testing.
What is the most reliable way to disable GC behavior for testing?
Use explicit engine configuration in code, such as config.wasm_gc(false), and test with a module that definitely depends on GC proposal features. That verifies the behavior much more reliably than an ambient environment variable alone.
The practical takeaway is simple: GC=no is easy to over-interpret. If you need deterministic behavior, enforce GC support through the Wasmtime engine configuration and validate using a known GC-dependent module.