swc-project/swc · error

Sourcemap proxy cannot be called in this context

Error message

Sourcemap proxy cannot be called in this context

What it means

PluginSourceMapProxy implements SourceMapper for code running inside an SWC wasm plugin by forwarding calls to host functions imported from the wasm module's env (here __span_to_source_proxy). Those extern imports can only be linked in a wasm32 plugin guest; the non-wasm32 compilation of span_to_source therefore ends in unimplemented!("Sourcemap proxy cannot be called in this context") to make any off-target use fail loudly.

Source

Thrown at crates/swc_plugin_proxy/src/source_map/plugin_source_map_proxy.rs:90

    where
        F: FnOnce(&str, usize, usize) -> Ret,
    {
        #[cfg(target_arch = "wasm32")]
        {
            use swc_common::plugin::serialized::ResultValue;

            let src: ResultValue<String, Box<SpanSnippetError>> =
                read_returned_result_from_host(|serialized_ptr| unsafe {
                    __span_to_source_proxy(sp.lo.0, sp.hi.0, serialized_ptr)
                })
                .expect("Host should return source code");

            let src = src.0?;
            return Ok(extract_source(&src, 0, src.len()));
        }

        #[cfg(not(target_arch = "wasm32"))]
        unimplemented!("Sourcemap proxy cannot be called in this context")
    }
}

/// Subset of SourceMap interface supported in plugin.
/// Unlike `Comments`, this does not fully implement `SourceMap`.
#[cfg(feature = "__plugin_mode")]
impl SourceMapper for PluginSourceMapProxy {
    #[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
    fn lookup_char_pos(&self, pos: BytePos) -> Loc {
        #[cfg(target_arch = "wasm32")]
        {
            let should_request_source_file = if self.source_file.get().is_none() {
                1
            } else {
                0
            };
            let partial_loc: PartialLoc = read_returned_result_from_host(|serialized_ptr| unsafe {
                __lookup_char_pos_source_map_proxy(

View on GitHub (pinned to 5176682b65)

Solutions

  1. Gate all PluginSourceMapProxy method calls behind #[cfg(target_arch = "wasm32")].
  2. In host-side tests, build a real swc_common::SourceMap (SourceMap::new + new_source_file) and pass that instead of the proxy.
  3. Run plugin integration tests through swc_plugin_runner with the actual compiled .wasm so host imports link.

Example fix

// before: panics when compiled for host
drop(proxy.span_to_source(sp, |src, a, b| src[a..b].to_string()));

// after: only call inside the plugin guest
#[cfg(target_arch = "wasm32")]
let snippet = proxy.span_to_source(sp, |src, a, b| src[a..b].to_string());
Defensive patterns

Strategy: validation

Validate before calling

// fail fast with a clear message before touching any proxy method
fn assert_wasm_guest_context(api: &'static str) {
    assert!(
        cfg!(target_arch = "wasm32"),
        "{api} on PluginSourceMapProxy is only callable inside a wasm32 plugin guest"
    );
}

Type guard

fn in_plugin_guest() -> bool {
    cfg!(target_arch = "wasm32")
}

Prevention

When it happens

Trigger: Calling PluginSourceMapProxy::span_to_source (the primitive behind span_to_snippet) in code compiled for a native target — unit tests of plugin helpers running on the host, or host code that constructs the proxy type instead of using the compiler's real SourceMap.

Common situations: Running a plugin crate's #[test] functions on the host toolchain (default `cargo test`) where proxy methods get touched; refactors that move source-map logic out of the wasm-gated plugin entry; CI check builds compiling plugin code for native.

Related errors


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