clockworklabs/SpacetimeDB · error
Local module schema inspection failed
Error message
Local module schema inspection failed
What it means
After reading the inspector's stdout, the CLI reaps the module inspector subprocess and requires a successful exit status. A non-zero status means the local inspector (the module run for schema extraction) crashed, panicked, or otherwise failed, so its schema cannot be trusted and inspection fails.
Solutions
- Run the module locally and fix the panic/trap reported in the inspector's stderr (module init or reducer panics are the usual cause).
- Rebuild the module matching the toolchain/ABI the inspector expects (align `spacetimedb` crate and CLI versions).
- Check inspector stderr and exit code for missing binaries or runtime issues; install missing dependencies.
- Verify with `spacetime publish` to a local server to see whether the module initializes correctly outside the extraction path.
Example fix
// before: module init panics during inspection
#[spacetimedb::reducer(init)]
fn init(ctx: &ReducerContext) { panic!("oops"); }
// after
#[spacetimedb::reducer(init)]
fn init(ctx: &ReducerContext) {
ctx.db.users.insert(User { id: 0 });
} Defensive patterns
Strategy: try-catch
Validate before calling
// run the module once locally and check it initializes cleanly
let status = std::process::Command::new(&inspector_path).arg(&module).status()?;
if !status.success() { return Err(anyhow!("module inspector would fail; fix module init first")); } Try / catch
match inspect_observed(...) {
Ok(observation) => use_schema(observation),
Err(e) if e.to_string().contains("inspection failed") => {
log::error!("module inspector exited non-zero: {e}; check module init/panic");
fix_module_and_retry();
}
Err(e) => return Err(e),
} Prevention
- Test that module init/preupload reducers run without panicking before extraction
- Keep CLI and spacetimedb crate versions aligned (same module ABI)
- Check inspector stderr for traps and missing runtime dependencies
When it happens
Trigger: `inspect_observed` calls `child.wait()` and the inspector process exits non-zero — e.g. the wasm module panics during initialization, the inspector binary is incompatible with the module, or the module traps while emitting its schema.
Common situations: A module whose `__preupload__`/init code panics; running the inspector against a module built for a different ABI/toolchain version; missing runtime dependencies for the inspector subprocess.
Related errors
- Found disallowed print statement(s). These will not be…
- Local module schema exceeds output limit
- Module exceeds publish size limit
- Cannot determine module type from file extension
- --env-only cannot reset a database
AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-09-20).
Data as JSON: /api/errors/e38110e80b4674f9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/schema_extract.rs:154
.kill_on_drop(true);
configure_inspector_environment(&mut command);
let mut child = command.spawn().context("Cannot start local module schema inspection")?;
observation.started(child.id());
let mut output = Vec::new();
let mut stdout = child
.stdout
.take()
.context("Module inspection stdout unavailable")?
.take(MAX_SCHEMA_BYTES + 1);
let result = tokio::select! {
biased;
_ = send.closed() => Err(anyhow::anyhow!("Module inspection cancelled")),
result = tokio::time::timeout(deadline, async {
stdout.read_to_end(&mut output).await.context("Cannot read local module schema")?;
ensure!(output.len() as u64 <= MAX_SCHEMA_BYTES, "Local module schema exceeds output limit");
let status = child.wait().await.context("Cannot reap local module inspector")?;
observation.reaped(status);
ensure!(status.success(), "Local module schema inspection failed");
Ok(())
}) => result.unwrap_or_else(|_| Err(anyhow::anyhow!("Local module schema inspection timed out"))),
};
if result.is_err() {
// Queue termination, then retain ownership through positive reaping.
let _ = child.start_kill();
let status = child
.wait()
.await
.context("Cannot reap failed local module inspector")?;
observation.reaped(status);
}
result?;
// Neither parser nor validation diagnostics may echo schema literals.
let SerdeWrapper::<RawModuleDef>(raw) = serde_json::from_slice(&output)
.map_err(|_| anyhow::anyhow!("Local module inspector returned invalid schema data"))?;
let schema =
ModuleDef::try_from(raw).map_err(|_| anyhow::anyhow!("Local module schema validation failed"))?;View on GitHub (pinned to eddf9f5014)