clockworklabs/SpacetimeDB · error
Local module inspection thread failed
Error message
Local module inspection thread failed
What it means
inspect_blocking runs the module inspector on a spawned OS thread and uses thread::join().map_err(|_| ...). The error fires when the inspection thread itself panicked (JoinError), meaning the local inspection machinery crashed before producing a result — not that the module failed inspection.
Solutions
- Re-run the command; transient thread/runtime failures may not recur.
- Inspect server logs / RUST_BACKTRACE to find the panic that killed the inspection thread.
- Check memory/thread limits of the environment (CI containers often restrict thread creation).
- If reproducible, file/debug the underlying panic in the inspector pipeline; this error masks its real cause.
Defensive patterns
Strategy: retry
Try / catch
// CLI: catch the anyhow error, log RUST_BACKTRACE, retry once
Prevention
- Ensure the environment allows thread creation and has adequate memory
- Set RUST_BACKTRACE=1 when debugging local inspection
- Keep CLI updated to avoid known panics in the inspect pipeline
When it happens
Trigger: Calling from_path (synchronous schema extraction) when the inner std::thread::spawn closure panics — e.g. the tokio current-thread runtime fails to build, or inspect_with panics on the worker thread.
Common situations: Environments where tokio runtime construction fails (resource limits), or a bug/panic inside the inspection pipeline; also reproducible in tests that force the inspection thread to panic.
Related errors
- a row was a sequence trigger but there was no generated…
- batch subscriptions without a module host are not supported…
- Cannot determine module type from file extension
- Duration overflows i64 microseconds
- Duration since Unix epoch overflows i64 microseconds
AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-09-20).
Data as JSON: /api/errors/6b7a00edd9a54627.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/schema_extract.rs:42
pub(crate) fn from_path(path: &Path) -> anyhow::Result<ModuleDef> {
let bytes = read_program(path)?;
let host_type = match path.extension().and_then(|ext| ext.to_str()) {
Some("wasm") => "Wasm",
Some("js") => "Js",
_ => anyhow::bail!("Cannot determine module type from file extension"),
};
inspect_blocking(extractor_path()?, bytes, host_type.into())
}
fn inspect_blocking(extractor: PathBuf, bytes: Vec<u8>, host_type: String) -> anyhow::Result<ModuleDef> {
std::thread::spawn(move || {
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()?
.block_on(inspect_with(extractor, bytes, host_type, INSPECT_TIMEOUT))
})
.join()
.map_err(|_| anyhow::anyhow!("Local module inspection thread failed"))?
}
pub(crate) fn read_program(path: &std::path::Path) -> anyhow::Result<Vec<u8>> {
use std::io::Read;
let mut bytes = Vec::new();
std::fs::File::open(path)?
.take(spacetimedb_client_api_messages::publish::MAX_MODULE_BYTES as u64 + 1)
.read_to_end(&mut bytes)?;
ensure!(
bytes.len() <= spacetimedb_client_api_messages::publish::MAX_MODULE_BYTES,
"Module exceeds publish size limit"
);
Ok(bytes)
}
const MAX_SCHEMA_BYTES: u64 = 16 * 1024 * 1024;
const INSPECT_TIMEOUT: Duration = Duration::from_secs(60);
View on GitHub (pinned to eddf9f5014)