denoland/deno · critical
Bootstrap exception: {error}
Error message
Bootstrap exception: {error} What it means
After the runtime is created, MainWorker::bootstrap invokes the cached bootstrap main function (99_main.js) with the bootstrap options. If that call throws a JS exception, it is converted via JsError::from_v8_exception and re-raised as a Rust panic, because a runtime that fails bootstrap cannot serve anything.
Source
Thrown at runtime/worker.rs:851
{
let op_state = self.js_runtime.op_state();
let mut state = op_state.borrow_mut();
state.put(options.clone());
if let Some((fd, serialization)) = options.node_ipc_init {
state.put(deno_node::ChildPipeFd(fd, serialization));
}
}
deno_core::scope!(scope, &mut self.js_runtime);
v8::tc_scope!(scope, scope);
let args = options.as_v8(scope);
let bootstrap_fn = self.bootstrap_fn_global.take().unwrap();
let bootstrap_fn = v8::Local::new(scope, bootstrap_fn);
let undefined = v8::undefined(scope);
bootstrap_fn.call(scope, undefined.into(), &[args]);
if let Some(exception) = scope.exception() {
let error = JsError::from_v8_exception(scope, exception);
panic!("Bootstrap exception: {error}");
}
if let Some(t) = t0 {
#[allow(clippy::print_stderr, reason = "diagnostic")]
{
eprintln!(
"[startup] {:>32} {:?}",
"MainWorker::bootstrap (99_main)",
t.elapsed()
);
}
}
}
#[cfg(not(target_os = "linux"))]
pub fn setup_memory_trim_handler(&mut self) {
// Noop
}
View on GitHub (pinned to a961cdec3b)
Solutions
- Rebuild startup snapshots after upgrading Deno crates so snapshot JS matches Rust ops
- Do not set skip_op_registration unless you re-register every op the snapshot JS calls
- Read the {error} text - it is the JS exception from 99_main.js (missing op, undefined function, etc.) and names the failing step
- Reproduce with a minimal extension set to identify which extension's JS fails
Defensive patterns
Strategy: validation
Try / catch
// Embedders can isolate bootstrap failures at startup
let boot = std::panic::catch_unwind(AssertUnwindSafe(|| worker.bootstrap(options)));
if boot.is_err() {
// snapshot/op mismatch: rebuild the snapshot before retrying, do not serve traffic
} Prevention
- Regenerate startup snapshots whenever deno_core/deno_runtime versions change
- Only set skip_op_registration when you re-register every op the snapshot JS references
- Add a startup smoke test that boots a worker with the real snapshot in CI
When it happens
Trigger: JS code in the bootstrap chain throwing: a startup snapshot that mismatches the Rust ops (e.g. skip_op_registration set without re-registering ops), a corrupted snapshot blob from a partial build, or embedder bootstrap options that violate invariants.
Common situations: Embedders building custom snapshots and workers; upgrading deno_core/deno_runtime while reusing an old snapshot; enabling skip_op_registration without supplying all ops.
Related errors
- Unsupported media type for snapshotting {media_type:?} for f
- Attempted to read snapshot data out of range: {id} (of {})
- Attempted to read the snapshot data at index {id} twice
- Invalid data type at index {id}, expected '{}'
- {path} exists
AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20).
Data as JSON: /api/errors/eca03433730946e6.
Report an issue: GitHub.