swc-project/swc · critical

Should able to deserialize

Error message

Should able to deserialize

What it means

Host import `get_experimental_transform_context`: it decodes the key that the plugin previously wrote into `mutable_context_key_buffer` from versioned CBOR into a String; decode failure panics. Unlike the pure host-side encodes, the input here is guest-produced, so a plugin that writes the key with mismatched bindings (different swc_core schema), writes nothing, or corrupts the buffer makes this panic reachable.

Source

Thrown at crates/swc_plugin_runner/src/imported_fn/metadata_context.rs:103

    };
    let value = VersionedSerializable::new(value);
    let serialized = PluginSerializedBytes::try_serialize(&value).expect("Should be serializable");

    allocate_return_values_into_guest(caller, allocated_ret_ptr, &serialized);

    1
}

#[cfg_attr(debug_assertions, tracing::instrument(level = "info", skip_all))]
pub fn get_experimental_transform_context(
    caller: &mut dyn runtime::Caller<'_>,
    env: &MetadataContextHostEnvironment,
    allocated_ret_ptr: u32,
) -> i32 {
    let context_key_buffer = env.mutable_context_key_buffer.lock();
    let key: String = PluginSerializedBytes::from_bytes(context_key_buffer.clone())
        .deserialize()
        .expect("Should able to deserialize")
        .into_inner();

    let value = env
        .metadata_context
        .experimental
        .get(&key)
        .map(|v| v.to_string());

    if let Some(value) = value {
        let serialized = PluginSerializedBytes::try_serialize(&VersionedSerializable::new(value))
            .expect("Should be serializable");

        allocate_return_values_into_guest(caller, allocated_ret_ptr, &serialized);

        return 1;
    }

    0

View on GitHub (pinned to 5176682b65)

Solutions

  1. Rebuild the plugin against the swc_core version matching the installed @swc/core
  2. Upgrade @swc/core and the plugin atomically
  3. If you own the plugin, ensure it sets the context key through the generated bindings instead of manual memory writes
  4. Report upstream with the plugin source if matched versions still fail

Example fix

# before
# host @swc/core new, plugin wasm old -> guest writes legacy key encoding

# after
cargo update -p swc_core --precise <host-matching version>
cargo build-wasi --release
Defensive patterns

Strategy: validation

Validate before calling

// before enabling experimental context features, assert matched versions
if (usesExperimentalContext(plugin)) {
  assertPluginHostAligned(plugin, coreVersion);
}

Try / catch

// the deserialization panic crosses FFI and aborts Node; contain it in a child process:
await execFile(node, ['plugin-job.js']).catch(e => { throw new Error(`experimental context decode failed: ${e}`); });

Prevention

When it happens

Trigger: A plugin calls get_experimental_transform_context after writing a key buffer whose bytes are not the expected versioned CBOR String - typically because the plugin's swc_core predates/postdates the host runner's wire format, or it skipped writing the key.

Common situations: Experimental-context plugin APIs used across an @swc/core upgrade; plugin binaries compiled with a different swc_core minor; bugs in custom plugins that mismanage the key buffer.

Related errors


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