clockworklabs/SpacetimeDB · error
Module exceeds publish size limit
Error message
Module exceeds publish size limit
What it means
The CLI's schema extraction reads a module file from disk and enforces the same publish size limit (`MAX_MODULE_BYTES`) that servers enforce, reading at most limit+1 bytes to detect overflow. It throws when the module binary on disk is larger than the maximum allowed publish size. This gives early, local feedback before any server interaction.
Solutions
- Build the module in release mode and strip debug info (e.g. `wasm-snip`, `wasm-opt -Oz`, or `strip`) to shrink the wasm below the limit.
- Check the file size first (`ls -lh target/wasm32-unknown-unknown/release/*.wasm`) and confirm you are extracting from the intended artifact.
- Remove or externalize large embedded data (assets, static strings) from the module.
- If the module genuinely needs more space, check whether the deployment's `MAX_MODULE_BYTES` permits it — the CLI enforces the same constant, so the module must shrink.
Example fix
// before: building with debug info wasm32-unknown-unknown/debug/my_module.wasm (> MAX_MODULE_BYTES) // after cargo build --release --target wasm32-unknown-unknown wasm-opt -Oz --strip-debug my_module.wasm -o my_module.wasm # now <= MAX_MODULE_BYTES
Defensive patterns
Strategy: validation
Validate before calling
use spacetimedb_client_api_messages::publish::MAX_MODULE_BYTES;
let size = std::fs::metadata(path)?.len();
if size > MAX_MODULE_BYTES as u64 {
return Err(anyhow!("module {} is {} bytes, limit is {}", path.display(), size, MAX_MODULE_BYTES));
} Try / catch
match read_program(&path) {
Ok(bytes) => proceed(bytes),
Err(e) if e.to_string().contains("publish size limit") => shrink_module_and_retry(),
Err(e) => return Err(e),
} Prevention
- Build modules in release mode and strip debug info
- Check wasm artifact size in CI before publishing/extracting
- Avoid embedding large assets in wasm binaries
When it happens
Trigger: Calling `read_program(path)` (via `SchemaExtract::from_path`) on a module `.wasm` whose file size exceeds `spacetimedb_client_api_messages::publish::MAX_MODULE_BYTES`.
Common situations: Building the module with debug symbols / unstripped wasm, accidentally bundling large assets into the wasm binary, or pointing the extractor at the wrong (larger) artifact file.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- Found disallowed print statement(s). These will not be…
- Local module schema exceeds output limit
- Local module schema inspection failed
- 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/79fef556f32ee6f0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/schema_extract.rs:51
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);
/// Inspect exactly the artifact bytes that will be uploaded. The private copy
/// prevents path replacement between inspection and upload, including --bin-path.
/// This invokes only local extraction, never a server or a saved CLI context.
pub(crate) async fn inspect(program: &[u8], host_type: &str) -> anyhow::Result<ModuleDef> {
let extractor = extractor_path()?;
inspect_with(extractor, program.to_vec(), host_type.to_owned(), INSPECT_TIMEOUT).await
}
pub(crate) async fn inspect_with(View on GitHub (pinned to eddf9f5014)