denoland/deno · error

Couldn't consume WasmStreamingResource.

Error message

Couldn't consume WasmStreamingResource.

What it means

WebAssembly.compileStreaming is backed by a WasmStreamingResource in Deno's resource table. On close, the runtime assumes it holds the only Rc reference and consumes it via Rc::try_unwrap to finish the stream; if another reference exists, the unwrap fails and the process panics. Users never touch this resource through the documented API, so hitting it implies manual resource manipulation or an internal lifecycle bug.

Source

Thrown at libs/core/ops_builtin.rs:291

    self.0.borrow_mut().on_bytes_received(&buf);
    Box::pin(std::future::ready(Ok(WriteOutcome::Full { nwritten })))
  }

  fn write_all(self: Rc<Self>, view: BufView) -> AsyncResult<()> {
    self.0.borrow_mut().on_bytes_received(&view);
    Box::pin(std::future::ready(Ok(())))
  }

  fn close(self: Rc<Self>) {
    // At this point there are no clones of Rc<WasmStreamingResource> on the
    // resource table, and no one should own a reference outside of the stack.
    // Therefore, we can be sure `self` is the only reference.
    match Rc::try_unwrap(self) {
      Ok(wsr) => {
        wsr.0.into_inner().finish();
      }
      _ => {
        panic!("Couldn't consume WasmStreamingResource.");
      }
    }
  }
}

/// Feed bytes to WasmStreamingResource.
#[op2(fast)]
pub fn op_wasm_streaming_feed(
  state: Rc<RefCell<OpState>>,
  #[smi] rid: ResourceId,
  #[buffer] bytes: &[u8],
) -> Result<(), ResourceError> {
  let wasm_streaming = state
    .borrow_mut()
    .resource_table
    .get::<WasmStreamingResource>(rid)?;

  wasm_streaming.0.borrow_mut().on_bytes_received(bytes);

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Never close wasm streaming resources manually — await the compileStreaming promise instead
  2. Let abort/failure paths settle before touching resource ids
  3. If the panic occurs without any manual resource management, update Deno and report the reproducer
  4. Minimize with a plain `await WebAssembly.compileStreaming(fetch(url))` loop when reporting

Example fix

// before — force-closing resources while a compile is pending
const p = WebAssembly.compileStreaming(fetch("./mod.wasm"));
for (const [rid] of Object.entries(Deno.resources())) Deno.close(Number(rid));

// after — await the promise; the runtime closes the resource itself
const mod = await WebAssembly.compileStreaming(fetch("./mod.wasm"));
Defensive patterns

Strategy: validation

Validate before calling

// track in-flight compilations; never close their resources
const pending = new Set<Promise<unknown>>();
function compile(url: string | URL) {
  const p = WebAssembly.compileStreaming(fetch(url)).finally(() => pending.delete(p));
  pending.add(p);
  return p;
}
await Promise.all(pending);

Prevention

When it happens

Trigger: Manually closing the streaming resource id (Deno.resources()/Deno.close on the rid of a pending compileStreaming), or internal code holding a clone while close runs — a lifecycle misuse rather than a normal API sequence.

Common situations: Tools that enumerate and aggressively close all open Deno resources; aborted or pipelined wasm compilations where cleanup races a live reference; deno_core bugs in the streaming lifecycle (fixed at the core level when found).

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/45e33ec0f5f852af. Report an issue: GitHub.