swc-project/swc · critical
Should able to write into memory view
Error message
Should able to write into memory view
What it means
After the guest allocator returns a pointer, the host writes the serialized program bytes into the plugin's wasm memory via view.write_buf(ptr_start, bytes). The expect panics when that write crosses the guest memory bounds - the allocator returned a bad pointer, the guest could not grow its memory (wasm max / store limits), or the pointer was computed against a different memory snapshot.
Source
Thrown at crates/swc_plugin_runner/src/memory_interop.rs:38
#[cfg_attr(debug_assertions, tracing::instrument(level = "info", skip_all))]
pub fn write_into_memory_view<F>(
view: &mut dyn runtime::Caller<'_>,
serialized_bytes: &PluginSerializedBytes,
get_allocated_ptr: F,
) -> (u32, u32)
where
F: Fn(&mut dyn runtime::Caller<'_>, usize) -> u32,
{
let serialized_len = serialized_bytes.as_slice().len();
let ptr_start = get_allocated_ptr(view, serialized_len);
let serialized_size = serialized_len
.try_into()
.expect("Should be able to convert to i32");
// Note: it's important to get a view from memory _after_ alloc completes
view.write_buf(ptr_start, serialized_bytes.as_slice())
.expect("Should able to write into memory view");
(ptr_start, serialized_size)
}
/// Set `return` value to pass into guest from functions returning values with
/// non-deterministic size like `Vec<Comment>`. Guest pre-allocates a struct to
/// contain ptr to the value, host in here allocates guest memory for the actual
/// value then returns its ptr with length to the preallocated struct.
#[cfg_attr(debug_assertions, tracing::instrument(level = "info", skip_all))]
pub fn allocate_return_values_into_guest(
caller: &mut dyn runtime::Caller<'_>,
allocated_ret_ptr: u32,
serialized_bytes: &PluginSerializedBytes,
) {
let serialized_bytes_len: usize = serialized_bytes.as_slice().len();
let serialized_bytes_len = serialized_bytes_len
.try_into()
.expect("Should be able to convert size");View on GitHub (pinned to 5176682b65)
Solutions
- Align the plugin's swc_core version with the host swc version and rebuild with wasm32-wasi --release.
- Reduce the payload: transform per module, keep files a reasonable size, avoid plugins on giant generated files.
- Capture the panic boundary with catch_unwind/subprocess isolation so the build reports the file instead of aborting.
- Check the plugin does not override or break the allocator (no custom global allocator in the guest).
Defensive patterns
Strategy: try-catch
Try / catch
// Wrap the whole plugin transform (alloc + write into guest memory) so an
// out-of-bounds write is a per-file error, not a process abort.
let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
compiler.process_js_file(&fm, &handler, &config_with_plugins)
}));
let out = match out {
Ok(r) => r,
Err(_) => {
tracing::error!(file = %fm.name, "plugin guest memory write failed; retrying without plugins");
compiler.process_js_file(&fm, &handler, &config_without_plugins)
}
}; Prevention
- Match plugin swc_core and host swc versions exactly on every upgrade.
- Keep per-file sizes moderate; huge files multiply serialized-copy pressure on guest memory.
- Run plugin transforms in a dedicated worker process for hard isolation.
- Watch for wasm store memory limits configured by your embedding runtime.
When it happens
Trigger: write_into_memory_view during PluginTransformExecutor::run: guest alloc 'succeeds' but ptr+len exceeds current memory size; guest memory.grow failed so the region is not mapped; plugin's allocator is corrupted or from an ABI-mismatched build.
Common situations: Very large files plus plugins that force big serialized AST copies; plugin built with mismatched swc_core (allocator protocol differs); wasm store memory limits configured in the embedding runtime.
Related errors
- Should able to read memory from given ptr
- Should able to be deserialized into string
- Should be serializable
- Should be serializable
- Should able to deserialize
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/3e59bde5669dd6ef.
Report an issue: GitHub.