denoland/deno · error
Couldn't consume WasmStreamingResource.
Error message
Couldn't consume WasmStreamingResource.
What it means
The abort path of Deno's wasm streaming: when a compilation is aborted, the op takes the WasmStreamingResource out of the resource table and must be its sole owner (Rc::try_unwrap) to call abort() on the underlying stream. If another Rc reference survives, the unwrap fails and the process panics. This is an internal lifecycle invariant; the documented API surface never exposes those references.
Source
Thrown at libs/core/ops_builtin_v8.rs:1464
state: Rc<RefCell<OpState>>,
rid: u32,
error: v8::Local<v8::Value>,
) -> Result<(), ResourceError> {
// NOTE: v8::WasmStreaming::abort can't be called while `state` is borrowed;
let wasm_streaming = state
.borrow_mut()
.resource_table
.take::<WasmStreamingResource>(rid)?;
// At this point there are no clones of Rc<WasmStreamingResource> on the
// resource table, and no one should own a reference because we're never
// cloning them. So we can be sure `wasm_streaming` is the only reference.
match std::rc::Rc::try_unwrap(wasm_streaming) {
Ok(wsr) => {
wsr.0.into_inner().abort(Some(error));
}
_ => {
panic!("Couldn't consume WasmStreamingResource.");
}
}
Ok(())
}
// This op calls `op_apply_source_map` re-entrantly.
#[op2(reentrant)]
pub fn op_destructure_error<'s, 'i>(
scope: &mut v8::PinScope<'s, 'i>,
error: v8::Local<'s, v8::Value>,
) -> JsError {
*JsError::from_v8_exception(scope, error)
}
/// Effectively throw an uncatchable error. This will terminate runtime
/// execution before any more JS code can run, except in the REPL where it
/// should just output the error to the console.
#[op2(fast, reentrant)]View on GitHub (pinned to 336da420f4)
Solutions
- Update Deno/deno_core — lifecycle races in the streaming resource are fixed at the core level
- Do not touch resource ids for in-flight wasm compilations; let the promise settle
- Reproduce minimally (compileStreaming plus a concurrent abort) and report to denoland/deno with the script
Example fix
// before — aborting while manually manipulating the resource id
const p = WebAssembly.compileStreaming(fetch("./mod.wasm"));
Deno.core.close(wasmRid); // during in-flight compilation
// after — only abort via the promise; never touch the rid
const p = WebAssembly.compileStreaming(fetch("./mod.wasm")).catch((e) => {
console.error("compile aborted:", e);
return null;
}); Defensive patterns
Strategy: validation
Validate before calling
// let abort flow through the promise; never touch the streaming rid
const mod = await WebAssembly.compileStreaming(fetch("./mod.wasm")).catch((e) => {
console.error("compile aborted:", e);
return null;
}); Prevention
- Abort wasm compilations by dropping/rejecting the promise, never by manipulating resource ids
- Await or settle all streaming compilations before teardown/cleanup code runs
- Report races between abort and completion with a minimal script — they are core-level fixes
When it happens
Trigger: A WebAssembly.compileStreaming promise being aborted or rejected while an extra reference to the streaming resource is alive — resource-table misuse by tooling, or a race between abort and completion inside deno_core. The sibling close() path in ops_builtin.rs has the identical guard.
Common situations: Custom tooling that holds or closes wasm resource ids during an in-flight compilation; races between abort and completion on older deno_core versions; practically unseen in normal CLI usage.
Related errors
- Couldn't consume WasmStreamingResource.
- wasm streaming callback invoked before the JS handler was se
- expected a function
- ${name} is already registered
- Unknown worker event: "${type}"
AI-assisted analysis of denoland/deno@336da420f4 (2026-08-20).
Data as JSON: /api/errors/f96dba1d82603cff.
Report an issue: GitHub.