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
- Re-run the command — transient resource exhaustion is the most common cause
- Inspect earlier stderr output for a Rust panic message naming the real failure
- Raise thread/memory limits (ulimit -u, container cgroup settings) if running under caps
- Update to the latest Deno patch release; the jupyter kernel is actively maintained
- 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
- Keep kernel launcher scripts tolerant of a single retry at startup
- Avoid launching the kernel under severely capped cgroups or low ulimit -u
- Pin a known-good Deno version for notebook workloads
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
- Expected 'fn' field in the first argument to be a bench func
- web workers are not supported
- failed to send request to tsc thread
- Unable to construct URL from the path of cwd: {}
- failed to evaluate expression
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/60cfa1bb6651ea53.
Report an issue: GitHub.