swc-project/swc · error

Plugin proxy does not work without serialization support

Error message

Plugin proxy does not work without serialization support

What it means

swc_plugin_proxy is the guest (in-plugin) half of SWC's wasm plugin interop, and memory_interop/read_returned_result_from_host.rs contains the helpers that copy host-returned bytes out of guest memory. The real implementation requires the serialization protocol compiled in via the encoding-impl feature (cbor4ii + swc_common/encoding-impl); without it, read_returned_result_from_host_inner is compiled as a stub that panics with unimplemented!("Plugin proxy does not work without serialization support") so a mis-featured build fails loudly instead of reading uninitialized guest memory.

Source

Thrown at crates/swc_plugin_proxy/src/memory_interop/read_returned_result_from_host.rs:26

#[cfg(target_arch = "wasm32")]
// `__free` is linked from `swc_core::plugin::memory`, which re-exports the
// allocator shim from `swc_plugin::allocation`. It must stay a linked plugin
// symbol instead of being modeled as an `env` host import.
extern "C" {
    fn __free(ptr: *mut u8, size: i32) -> i32;
}
#[cfg(target_arch = "wasm32")]
impl Drop for AllocatedBytesPtr {
    fn drop(&mut self) {
        unsafe {
            __free(self.0 as _, self.1 as _);
        }
    }
}

#[cfg(not(feature = "encoding-impl"))]
fn read_returned_result_from_host_inner<F>(f: F) -> Option<AllocatedBytesPtr> {
    unimplemented!("Plugin proxy does not work without serialization support")
}

/// Performs an interop while calling host fn to get non-determined size return
/// values from the host. This is based on the contract between host's imported
/// fn, by imported fn allocated memory for the guest space then hand over its
/// ptr and length via a struct. Refer plugin_runner/imported_fn/mod.rs for the
/// detail.
///
/// Returns a struct AllocatedBytesPtr to the ptr for actual return value if
/// host fn allocated return value, None otherwise.
#[cfg(all(
    feature = "encoding-impl",
    feature = "__plugin_mode",
    target_arch = "wasm32"
))]
#[cfg_attr(debug_assertions, tracing::instrument(level = "info", skip_all))]
fn read_returned_result_from_host_inner<F>(f: F) -> Option<AllocatedBytesPtr>
where

View on GitHub (pinned to 5176682b65)

Solutions

  1. Enable the serialization feature: swc_plugin_proxy = { features = ["plugin-rt"] } (plugin-rt/plugin-mode both imply encoding-impl), or depend on swc_plugin_runner with its encoding-impl feature.
  2. Verify feature resolution with `cargo tree -e features -i swc_plugin_proxy` and confirm the encoding-impl edge appears.
  3. If this is a host-side build that should never execute plugin-proxy interop, remove or cfg-gate the code path constructing/calling the proxy.

Example fix

# before
[dependencies]
swc_plugin_proxy = { version = "30", default-features = false }

# after: plugin-rt implies encoding-impl
[dependencies]
swc_plugin_proxy = { version = "30", features = ["plugin-rt"] }
Defensive patterns

Strategy: validation

Validate before calling

# verify serialization support is compiled in before running plugin code
cargo tree -e features -i swc_plugin_proxy | grep -E 'encoding-impl|plugin-rt|plugin-mode' \
  || echo 'swc_plugin_proxy built WITHOUT serialization support — interop calls will panic'

Prevention

When it happens

Trigger: Compiling swc_plugin_proxy without the encoding-impl feature (default-features = false, or a dependency graph that only enables __plugin_mode without plugin-rt/plugin-mode) and then reaching any host-interop read path that calls read_returned_result_from_host_inner inside a plugin.

Common situations: Embedding swc plugin crates in a larger workspace where another dependency pins swc_plugin_proxy with default features off; feature-name drift across swc versions; hand-rolled feature sets that enable __plugin_mode directly instead of the bundling features.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/392297db1aa84f1b. Report an issue: GitHub.