clockworklabs/SpacetimeDB · error

Local module schema exceeds output limit

Error message

Local module schema exceeds output limit

What it means

When inspecting a locally-run module for its schema, the CLI reads the inspector's stdout capped at `MAX_SCHEMA_BYTES + 1` and throws if the schema output exceeds `MAX_SCHEMA_BYTES`. This bounds memory usage of the local inspection subprocess; oversized output aborts inspection instead of buffering unboundedly.

Solutions

  1. Reduce schema size: consolidate or remove auto-generated tables/reducers/types from the module before inspection.
  2. Check that the inspector command targets the correct module binary and that nothing else writes to stdout in the inspector path.
  3. Inspect only the needed subset of the schema (filter tables/reducers) if the extraction tooling allows scoping.
  4. If legitimately large schemas are needed, request a higher `MAX_SCHEMA_BYTES` in the tooling or use server-side inspection instead of the local capped path.

Example fix

// before: module emits entire schema, exceeds MAX_SCHEMA_BYTES
// after: scope extraction to the tables you need
//   or trim generated schema before inspection
let schema = extract_schema_filter(&module, /* tables: */ ["users", "orders"]);
Defensive patterns

Strategy: validation

Validate before calling

// estimate schema size before running local inspection
// e.g. count declared tables/reducers at compile time or via the build script
if schema_table_count > MAX_SCHEMA_TABLES_HINT {
    // scope extraction to needed tables first
}

Try / catch

match inspect_observed(...) {
    Ok(observation) => use_schema(observation),
    Err(e) if e.to_string().contains("exceeds output limit") => scope_extraction_smaller(),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Running local module inspection (`inspect_observed`, via `inspect_with`) where the module's schema JSON printed to stdout is larger than `MAX_SCHEMA_BYTES` — typically a module with a very large number of tables/reducers/types.

Common situations: Auto-generated or codegen-heavy modules declaring thousands of tables; schema output including verbose debug info; accidentally invoking the inspector against the wrong binary that dumps non-schema data.

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


AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-09-20). Data as JSON: /api/errors/f7832349e3193cc8. Report an issue: GitHub.

Appendix: source

Thrown at crates/cli/src/schema_extract.rs:151

                .stdin(Stdio::null())
                .stdout(Stdio::piped())
                .stderr(Stdio::null())
                .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)

View on GitHub (pinned to eddf9f5014)