clockworklabs/SpacetimeDB · critical
JS worker panicked during startup
Error message
JS worker panicked during startup
What it means
The V8 worker thread wraps the whole isolate startup — evaluating builtins and running startup_instance_worker — in panic::catch_unwind. If the Rust side of the worker panics (as opposed to a JS exception, which catch_exception handles and reports differently), the panic is caught and reported to whoever awaits the startup result as this error. The isolate never comes up for this generation; when it happens while recreating an isolate it is logged instead of sent over the channel.
Source
Thrown at crates/core/src/host/v8/mod.rs:1650
Either::Left(module) => (module.replica_ctx(), module.scheduler()),
Either::Right(mcc) => (&mcc.replica_ctx, &mcc.scheduler),
};
let instance_env = InstanceEnv::new(replica_ctx.clone(), scheduler.clone());
scope.set_slot(JsInstanceEnv::new(instance_env));
let startup_result = panic::catch_unwind(AssertUnwindSafe(|| {
catch_exception(scope, |scope| Ok(builtins::evaluate_builtins(scope)?))
.expect("our builtin code shouldn't error");
// Setup the JS module, find call_reducer, and maybe build the module.
startup_instance_worker(scope, program.clone(), generation_module_or_mcc)
}));
let (hooks, module_common) = match startup_result {
Err(_) => {
if let Some(result_tx) = startup_result_tx.take() {
if result_tx
.send(Err(anyhow::anyhow!("JS worker panicked during startup")))
.is_err()
{
log::error!("startup result receiver disconnected");
}
} else {
log::error!("JS worker panicked while recreating isolate");
}
return;
}
Ok(Err(err)) => {
if let Some(result_tx) = startup_result_tx.take() {
if result_tx.send(Err(err)).is_err() {
log::error!("startup result receiver disconnected");
}
} else {
log::error!("failed to restart JS worker: {err:#}");
}
return;View on GitHub (pinned to 524b4487d9)
Solutions
- Collect the panic backtrace from host logs (run with RUST_BACKTRACE=1) — this is a host-side failure, not a module error.
- Free memory or raise container limits and retry the publish; isolate creation is memory-hungry.
- Redeploy on a host build where the V8 startup path is known-good (pin or upgrade the host version).
- If it reproduces, minimize the module and report it upstream with the backtrace.
Defensive patterns
Strategy: retry
Try / catch
match startup_rx.await {
Err(e) if e.to_string().contains("panicked during startup") => {
// transient host-side failure: free resources, collect RUST_BACKTRACE=1 logs,
// recycle the worker / redeploy with backoff
restart_worker_with_backoff().await
}
other => other,
} Prevention
- Run the host with RUST_BACKTRACE=1 so panics carry a trace in logs.
- Size host memory for isolate-creation spikes.
- Pin a known-good host version and upgrade deliberately.
When it happens
Trigger: A Rust-level panic in the host's V8 integration during startup: isolate or platform initialization failure, out-of-memory while creating the isolate or compiling builtins, or a bug in the startup path (unwrap on None, index out of bounds) — distinct from user JS errors which surface as JS exceptions.
Common situations: Memory-constrained hosts where isolate allocation aborts; v8 platform flags or versions mismatched with the host build; host regressions in builtin evaluation after an upgrade; repeated crashes while recreating isolates for a new module generation.
Related errors
- Math.random is not available in SpacetimeDB modules. Use ctx
- The encoding label provided is invalid
- Option 'ignoreBOM' not supported
- Option 'stream' not supported
- Unable to read public key for JWT token verification
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/db47fa58fe9d2021.
Report an issue: GitHub.