{"record":{"id":"cc2b02a43c661484","repo":"clockworklabs/SpacetimeDB","slug":"exporting-something-that-is-not-a-spacetime-export","errorCode":null,"errorMessage":"exporting something that is not a spacetime export","messagePattern":"exporting something that is not a spacetime export","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/server/schema.ts","lineNumber":829,"sourceCode":"}\n\nfunction registerModuleExports(\n  schema: SchemaInner,\n  exports: object,\n  opts?: { ignoreNonModuleExports?: boolean }\n) {\n  if (schema.exportsRegistered) {\n    return;\n  }\n  schema.exportsRegistered = true;\n\n  for (const [name, moduleExport] of Object.entries(exports)) {\n    if (name === 'default') continue;\n    if (!isModuleExport(moduleExport)) {\n      if (opts?.ignoreNonModuleExports) {\n        continue;\n      }\n      throw new TypeError('exporting something that is not a spacetime export');\n    }\n    checkExportContext(moduleExport, schema);\n    moduleExport[registerExport](schema, name);\n  }\n}\n\nexport function schema<\n  const H extends Record<string, SchemaEntry>,\n  const E extends EnvironmentSchema = {},\n>(\n  entries: H,\n  moduleSettings?: ModuleSettings<E>\n): Schema<SchemaDefForEntries<H> & { env: E }> {\n  const ctx = new SchemaInner<SchemaDefForEntries<H> & { env: E }>(ctx => {\n    ctx.moduleDef.environment = environmentDeclarations(\n      moduleSettings?.env ?? {}\n    );\n    // Apply module settings.","sourceCodeStart":811,"sourceCodeEnd":847,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/bindings-typescript/src/server/schema.ts#L811-L847","documentation":"During `buildRawModuleDefV10`, `registerModuleExports` iterates the module's exports and requires every non-`default` export to be a spacetime export — an object/function carrying the hidden `registerExport` marker (`isModuleExport`). Plain functions, constants, classes, or third-party values exported from the module entry throw 'exporting something that is not a spacetime export'. The `default` export (the schema/router) is explicitly skipped.","triggerScenarios":"`export const VERSION = '1.0';`, `export function helper() {}`, `export class Foo {}`, or re-exporting a non-spacetime symbol from the module entry; exporting a type-assertion helper next to reducers. Submodule dispatch skips non-exports internally via `ignoreNonModuleExports: true`, but the top-level registration does not.","commonSituations":"Growing a module entry with utility exports (`export { connect }` helpers for tests); barrel files re-exporting test fixtures; library modules whose public API mixes spacetime exports with ordinary constants.","solutions":["Remove non-spacetime exports from the module entry file: keep helpers module-local (no `export`) or move them to a separate non-entry file.","Keep only spacetime exports (reducers, procedures, views, tables via the schema, HTTP handlers/router) and the `default` schema/router export in the entry.","If you need to expose constants, put them in a sibling file that is not the module entry compiled for publish."],"exampleFix":"// before (module entry)\nexport const TICK_RATE = 5; // plain constant\nexport const tick = spacetimedb.reducer(...);\nexport default schema({ ... });\n\n// after (module entry)\nconst TICK_RATE = 5; // module-local\nexport const tick = spacetimedb.reducer(...);\nexport default schema({ ... });","handlingStrategy":"type-guard","validationCode":"// Before publish, scan entry exports and fail with your own message listing offenders.\nfunction assertOnlySpacetimeExports(exports: Record<string, unknown>) {\n  const bad = Object.entries(exports)\n    .filter(([name, exp]) => name !== 'default' && !spacetimeExportNames.has(exp));\n  if (bad.length > 0) throw new Error(`non-spacetime exports: ${bad.map(b => b[0]).join(', ')}`);\n}\n// spacetimeExportNames = a Set you populate whenever you create a reducer/view/handler","typeGuard":"// Structural guard mirroring isModuleExport (needs access to the same symbol module):\nfunction isModuleExport(x: unknown): boolean {\n  return (typeof x === 'function' || typeof x === 'object') && x !== null && 'registerExport' in (x as object);\n}","tryCatchPattern":null,"preventionTips":["Keep the module entry minimal: spacetime exports plus `export default schema/router`.","Put helper functions, constants, and types in separate non-entry files.","Add a lint rule or script that flags unknown export names in the entry file."],"tags":["exports","module-system","build-time","spacetimedb","typescript"],"backgroundTag":"invalid-module-export","analyzedSha":"eddf9f5014579a50d4b67630e28b6e15cad9c4af","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}