clockworklabs/SpacetimeDB · critical
must export schema as default export
Error message
must export schema as default export
What it means
When a JavaScript (V8) module starts, the host evaluates the module, reads its default export, and derives the hook functions (reducers, tables, lifecycle) from it. Here get_hooks returned None: the module did not yield hooks from a default export, most simply because no usable default export exists. Without it the host cannot build the module description, so instance startup fails.
Source
Thrown at crates/core/src/host/v8/mod.rs:1187
None
}
}
/// Performs some of the shared startup work for JS worker isolates.
///
/// NOTE(centril): in its own function due to lack of `try` blocks.
fn startup_instance_worker<'scope>(
scope: &mut PinScope<'scope, '_>,
program: Arc<str>,
module_or_mcc: Either<ModuleCommon, ModuleCreationContext>,
) -> anyhow::Result<(HookFunctions<'scope>, ModuleCommon)> {
let hook_functions = catch_exception(scope, |scope| {
// Start-up the user's module.
let exports_obj = eval_user_module(scope, &program)?;
// Find the hook functions.
let hooks =
get_hooks(scope, exports_obj)?.ok_or_else(|| anyhow::anyhow!("must export schema as default export"))?;
Ok(hooks)
})?;
// If we don't have a module, make one.
let module_common = match module_or_mcc {
Either::Left(module_common) => module_common,
Either::Right(mcc) => {
let def = extract_description(scope, &hook_functions, &mcc.replica_ctx)?;
// Validate and create a common module from the raw definition.
build_common_module_from_raw(mcc, def)?
}
};
Ok((hook_functions, module_common))
}
/// Returns a new isolate.View on GitHub (pinned to 524b4487d9)
Solutions
- Ensure the module entry default-exports the schema the bindings generate: `export default schema;`.
- Rebuild the bundle and inspect the dist output to confirm the default export survived bundling.
- Regenerate or upgrade the JS bindings so the module is built for the ABI version the host expects.
- Reproduce locally against the same host version before republishing.
Example fix
// before: schema built but never exported as default
export const reducers = { /* ... */ };
// after: default-export the schema object the host expects
const schema = buildSchema({ /* ... */ });
export default schema; Defensive patterns
Strategy: validation
Validate before calling
// pre-deploy smoke check (Node): the built bundle must default-export the schema
const mod = await import('./dist/module.js');
if (mod.default === undefined) {
throw new Error('module must default-export its schema');
} Type guard
export function isSchemaExport(v: unknown): v is { reducers: Record<string, unknown> } {
return typeof v === 'object' && v !== null && 'reducers' in v;
} Prevention
- Always `export default schema` from the generated bindings.
- Smoke-test the built bundle's exports in CI before deploy.
- Regenerate bindings whenever the host version changes.
When it happens
Trigger: Publishing a JS module whose bundle does not export the schema object as the default export: a missing export statement, a bundler step that dropped or renamed the default export, or a module built against bindings that do not produce the expected export shape.
Common situations: Bundler configs (minification, library mode) that rewrite or drop default exports; modules written against an old bindings generation whose export convention differs from the host's ABI expectations; partially uploaded or truncated JS bundles.
Related errors
- default export is not a Schema object
- Math.random is not available in SpacetimeDB modules. Use ctx
- The encoding label provided is invalid
- Option 'ignoreBOM' not supported
- Option 'stream' not supported
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/1c55ab1360de07f5.
Report an issue: GitHub.