swc-project/swc · critical

Should be serializable

Error message

Should be serializable

What it means

Host import backing a plugin's hygiene query `$hygiene::mark_is_descendant_of`. It computes `Mark::is_descendant_of` on the host, wraps the boolean plus marks into `MutableMarkContext`, and encodes it as versioned CBOR; the `.expect("Should be serializable")` fires if encoding fails. Encoding three u32 fields cannot fail in a correct build, so hitting this panic signals a broken host/guest pairing (divergent swc_core schema) or memory corruption in the runner.

Source

Thrown at crates/swc_plugin_runner/src/imported_fn/hygiene.rs:46

pub fn mark_is_descendant_of_proxy(
    caller: &mut dyn runtime::Caller<'_>,
    _env: &BaseHostEnvironment,
    self_mark: u32,
    ancestor: u32,
    allocated_ptr: u32,
) {
    let self_mark = Mark::from_u32(self_mark);
    let ancestor = Mark::from_u32(ancestor);

    let return_value = self_mark.is_descendant_of(ancestor);

    let context = VersionedSerializable::new(MutableMarkContext(
        self_mark.as_u32(),
        0,
        return_value as u32,
    ));
    let serialized_bytes =
        PluginSerializedBytes::try_serialize(&context).expect("Should be serializable");

    write_into_memory_view(caller, &serialized_bytes, |_, _| allocated_ptr);
}

#[cfg_attr(debug_assertions, tracing::instrument(level = "info", skip_all))]
pub fn mark_least_ancestor_proxy(
    caller: &mut dyn runtime::Caller<'_>,
    _env: &BaseHostEnvironment,
    a: u32,
    b: u32,
    allocated_ptr: u32,
) {
    let a = Mark::from_u32(a);
    let b = Mark::from_u32(b);

    let return_value = Mark::least_ancestor(a, b).as_u32();

    let context =

View on GitHub (pinned to 5176682b65)

Solutions

  1. Align the plugin's swc_core dependency with the version embedded in the installed @swc/core and rebuild
  2. Upgrade @swc/core and every swc plugin atomically
  3. Bisect plugins (disable each) to identify the incompatible binary
  4. Report to swc-project/swc with exact @swc/core and swc_core versions if alignment does not fix it

Example fix

# before
# plugin Cargo.toml: swc_core = "=0.90.x" ; host: @swc/core with swc_core 0.100.x

# after
# plugin Cargo.toml pinned to the host's version
swc_core = "=0.100.x"
# then: cargo build-wasi --release and redeploy the .wasm
Defensive patterns

Strategy: validation

Validate before calling

// assert plugin/host compatibility before running transforms
const hostSwcCore = swcCoreEmbeddedVersion(); // from @swc/core release notes/lockfile
const pluginSwcCore = require('my-swc-plugin/swc_core_version.json').version;
if (majorOrMinor(hostSwcCore) !== majorOrMinor(pluginSwcCore)) {
  throw new Error(`hygiene proxy schema mismatch: host ${hostSwcCore} vs plugin ${pluginSwcCore}`);
}

Try / catch

// embed the transform and catch the unwind, mapping it to a plugin-disable decision:
let result = std::panic::catch_unwind(|| run_plugin_transform());
if result.is_err() -> log 'plugin crashed, falling back to plugin-less transform' and retry without plugins

Prevention

When it happens

Trigger: A wasm plugin calls the mark_is_descendant_of host import while the plugin's swc_core guest bindings were compiled against a different version than the host swc_plugin_runner, or the cbor4ii encoder hits an internal error.

Common situations: Version drift between @swc/core and plugin builds after a partial upgrade; plugins compiled on a different swc_core minor with changed hygiene proxy ABI; rare encoder bugs in cbor4ii.

Related errors


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