denoland/deno · critical

REPL thread failed to start

Error message

REPL thread failed to start

What it means

During `deno jupyter` startup the CLI spawns a dedicated thread that runs the REPL session (an isolated server) and waits on a channel for the isolate handle. This error means the channel sender was dropped before any handle arrived: the REPL thread ended early, almost certainly because session.start() panicked or the thread/runtime failed to spawn. The ZMQ kernel cannot come up in this state, so startup aborts.

Source

Thrown at cli/tools/jupyter/mod.rs:188

        .thread_safe_handle();
      let _ = isolate_handle_tx.send(handle);

      // Service REPL requests until channel closes.
      let mut session = JupyterReplSession {
        repl_session,
        rx: repl_req_rx,
      };
      session.start().await;

      Ok::<(), AnyError>(())
    };
    deno_runtime::tokio_util::create_and_run_current_thread(fut)
  });

  // Wait for the REPL to be ready.
  let isolate_handle = isolate_handle_rx
    .await
    .map_err(|_| anyhow!("REPL thread failed to start"))?;

  // --- Create the ZMQ kernel worker on the main thread ---------------
  let kernel_main_module = resolve_url_or_path(
    "./$deno$jupyter_kernel.mts",
    cli_options.initial_cwd(),
  )
  .unwrap();

  let (worker2, _) = create_single_test_event_channel();
  let TestEventWorkerSender {
    sender: _test_sender2,
    stdout: stdout2,
    stderr: stderr2,
  } = worker2;

  let cwd_url =
    Url::from_directory_path(cli_options.initial_cwd()).map_err(|_| {
      anyhow!(

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Re-run the command — transient resource exhaustion is the most common cause
  2. Inspect earlier stderr output for a Rust panic message naming the real failure
  3. Raise thread/memory limits (ulimit -u, container cgroup settings) if running under caps
  4. Update to the latest Deno patch release; the jupyter kernel is actively maintained
  5. If it reproduces on current Deno, file an issue with the panic backtrace
Defensive patterns

Strategy: retry

Validate before calling

# sanity-check that deno can start a runtime in this environment
deno eval 'console.log("ok")' >/dev/null 2>&1 || { echo "deno runtime broken/exhausted" >&2; exit 2; }
deno jupyter kernel

Try / catch

// wrapper around the kernel launch: one bounded retry on this transient failure
import { spawnSync } from "node:child_process";
const run = () => spawnSync("deno", ["jupyter", "kernel"], { stdio: "inherit" });
let r = run();
if (r.status !== 0 && /REPL thread failed to start/.test(String(r.stderr))) {
  r = run(); // transient thread-spawn failures often clear immediately
}
process.exit(r.status ?? 1);

Prevention

When it happens

Trigger: `deno jupyter` kernel startup where the spawned REPL thread exits before signaling readiness: a panic inside the session start path, tokio current-thread runtime creation failure, or resource exhaustion (thread/memory caps via ulimit or cgroups).

Common situations: Containers with low thread or memory limits; sandboxing (SELinux/seccomp) blocking thread creation; corrupted Deno installs after interrupted upgrades; rarely, Deno bugs in the jupyter subsystem on specific versions.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/60cfa1bb6651ea53. Report an issue: GitHub.