swc-project/swc · critical
Should able to be deserialized into string
Error message
Should able to be deserialized into string
What it means
Host-side handler for a wasm plugin's `emit` call in swc_plugin_runner. It copies bytes from the plugin's linear memory and decodes them as versioned CBOR into `PluginEmitOutput`; when decoding fails, the `.expect(...)` panics. The bytes were encoded by the guest using its own swc_core serialization code, so this panic almost always means the plugin was built against a swc_core whose wire schema differs from the host runner's, or the guest wrote garbage/incorrect length.
Source
Thrown at crates/swc_plugin_runner/src/imported_fn/handler.rs:45
);
builder.emit();
})
}
}
pub fn emit_output(
caller: &mut dyn runtime::Caller<'_>,
_env: &BaseHostEnvironment,
output_ptr: i32,
output_len: i32,
) {
let mut output_bytes = Vec::new();
copy_bytes_into_host(caller, output_ptr, output_len, &mut output_bytes);
let serialized = PluginSerializedBytes::from_bytes(output_bytes);
let output = PluginSerializedBytes::deserialize::<swc_common::plugin::emit::PluginEmitOutput>(
&serialized,
)
.expect("Should able to be deserialized into string");
experimental_emit(output.0.key, output.0.value);
}
View on GitHub (pinned to 5176682b65)
Solutions
- Rebuild the plugin against the exact swc_core version shipped in your @swc/core release and redeploy
- Upgrade @swc/core and all swc plugins together in one coordinated change (check each plugin's peerDependencies)
- Temporarily disable plugins one by one to confirm which one emits the incompatible bytes
- If versions provably match, open an issue on swc-project/swc with the plugin wasm, @swc/core version, and a minimal repro
Example fix
# before # @swc/core@1.3.100 (embeds swc_core X) + plugin built against swc_core X-3 # after # in the plugin crate: cargo update -p swc_core --precise <version matching @swc/core 1.3.100> cargo build-wasi --release && cp target/wasm32-wasi/release/*.wasm ./
Defensive patterns
Strategy: validation
Validate before calling
// before loading plugins, verify the host runner can serve them
const semver = require('semver');
const coreVersion = require('@swc/core/package.json').version;
for (const [name] of swcConfig.jsc.experimental.plugins) {
const peer = require(`${name}/package.json`).peerDependencies?.['@swc/core'];
if (peer && !semver.satisfies(coreVersion, peer)) {
throw new Error(`${name} requires @swc/core ${peer}, host has ${coreVersion}`);
}
} Try / catch
// Rust hosts embedding swc_plugin_runner can contain the panic:
let out = std::panic::catch_unwind(AssertUnwindSafe(|| transform_with_plugins()))
.map_err(|_| anyhow::anyhow!("plugin emit output failed to decode; rebuild plugin against the host swc_core"));
// Node users: run plugin-enabled transforms in a worker/child process so a native panic cannot take down the main process Prevention
- Treat @swc/core and swc plugin versions as one unit in the lockfile
- In-house plugins: CI job that rebuilds wasm against the exact swc_core of the app's @swc/core
- Pin exact versions (no ^ ranges) for @swc/core when plugins are enabled
When it happens
Trigger: A swc wasm plugin calls the emit host import while its guest bindings (swc_core version) do not match the swc_plugin_runner version embedded in the installed @swc/core; or the plugin returns malformed output_ptr/output_len.
Common situations: Upgrading @swc/core without rebuilding/reinstalling third-party plugins; plugins built from source with a stale Cargo.lock pinning an older swc_core; mixing plugin builds targeting wasm32-wasi with an incompatible host; custom plugins in a monorepo drifting from the app's @swc_core version.
Related errors
- Should able to deserialize
- Should be serializable
- Should be serializable
- Should be serializable
- Should able to read memory from given ptr
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/da3f335b9c9e8042.
Report an issue: GitHub.