clockworklabs/SpacetimeDB · error · TypeError
schema entry ' ' looks like a default import; use `import *…
Error message
schema entry '${accName}' looks like a default import; use `import * as ${accName} from '...'` so the submodule can see the library's named reducer exports. What it means
Entries in the object passed to `schema({...})` must be tables or submodule namespace objects. If an entry is itself a `Schema` instance (`entry instanceof Schema`), the usual cause is a default import of a library module (`import Lib from 'lib'` yields the schema) used directly as an entry. The error message is prescriptive: re-import as a namespace so the schema can see and register the library's named reducer exports.
Solutions
- Change to a namespace import: `import * as scheduledLib from '../lib';` and keep `schema({ scheduledLib })`.
- Make sure the library file has named exports for its reducers/tables; the schema entry must be the namespace object, not the library's default export.
- If the entry should be a table, pass the `table()` handle directly instead of the module/schema object.
Example fix
// before
import scheduledLib from '../lib'; // default import = Schema instance
export default schema({ users, scheduledLib }); // TypeError
// after
import * as scheduledLib from '../lib';
export default schema({ users, scheduledLib }); Defensive patterns
Strategy: type-guard
Validate before calling
// Normalize schema entries: reject Schema instances before calling schema().
import { Schema } from '...';
function assertEntries(entries: Record<string, unknown>) {
for (const [name, entry] of Object.entries(entries)) {
if (entry instanceof Schema) throw new Error(`${name} is a Schema; use a namespace import`);
}
} Type guard
function isSchemaInstance(x: unknown): x is Schema { return x instanceof Schema; } Prevention
- Use `import * as lib from 'lib'` for any module passed as a schema entry.
- Watch for auto-import quick-fixes that silently switch namespace imports to default imports.
- Keep the library's default export for external consumers, but never feed it to schema().
When it happens
Trigger: `import scheduledLib from '../lib'; export default schema({ scheduledLib })` where the library's default export is a `Schema`; mixing up the library's default export (schema) with its namespace (tables + reducers); refactoring an import from `import * as x` to `import x` during a cleanup.
Common situations: Integrating a shared spacetime library as a submodule; auto-fix/'add missing imports' switching to a default import; copy-pasting integration snippets with the wrong import style.
Related errors
- invalid sequence type
- multiple schemas are not supported
- schema entry ' ' must be a table or a submodule namespace…
- exporting something that is not a spacetime export
- HTTP handler ' ' was exported more than once
AI-assisted analysis of clockworklabs/SpacetimeDB@eddf9f5014 (2026-08-20).
Data as JSON: /api/errors/92f8213c4a1b36d3.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-typescript/src/server/schema.ts:855
const H extends Record<string, SchemaEntry>,
const E extends EnvironmentSchema = {},
>(
entries: H,
moduleSettings?: ModuleSettings<E>
): Schema<SchemaDefForEntries<H> & { env: E }> {
const ctx = new SchemaInner<SchemaDefForEntries<H> & { env: E }>(ctx => {
ctx.moduleDef.environment = environmentDeclarations(
moduleSettings?.env ?? {}
);
// Apply module settings.
if (moduleSettings?.CASE_CONVERSION_POLICY != null) {
ctx.setCaseConversionPolicy(moduleSettings.CASE_CONVERSION_POLICY);
}
const tableSchemas: Record<string, UntypedTableDef> = {};
for (const [accName, entry] of Object.entries(entries)) {
if (entry instanceof Schema) {
throw new TypeError(
`schema entry '${accName}' looks like a default import; use \`import * as ${accName} from '...'\` so the submodule can see the library's named reducer exports.`
);
}
if (isSubmoduleNamespace(entry)) {
const { rawDef, dispatch } =
entry.default.buildSubmoduleDispatch(entry);
dispatch.namespace = accName;
ctx.addSubmodule({ namespace: accName, module: rawDef });
ctx.submoduleDispatchInfos.push(dispatch);
continue;
}
if (!isUntypedTableSchema(entry)) {
throw new TypeError(
`schema entry '${accName}' must be a table or a submodule namespace object`
);
}
const table = entry;View on GitHub (pinned to eddf9f5014)