{"record":{"id":"b897b646667d1b64","repo":"clockworklabs/SpacetimeDB","slug":"default-export-is-not-a-schema-object","errorCode":null,"errorMessage":"default export is not a Schema object","messagePattern":"default export is not a Schema object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/core/src/host/v8/syscall/mod.rs","lineNumber":145,"sourceCode":") -> Result<Option<HookFunctions<'scope>>, ErrorOrException<ExceptionThrown>> {\n    // We only set RECV_SLOT_INDEX in set_registered_hooks, which is only called in\n    // the v2 code path. Set it to undefined ahead of time so it's not a garbage value.\n    scope\n        .get_current_context()\n        .set_embedder_data(hooks::RECV_SLOT_INDEX, v8::undefined(scope).into());\n    if let Some(hooks) = get_registered_hooks(scope) {\n        return Ok(Some(hooks));\n    }\n\n    let default = super::str_from_ident!(default).string(scope);\n    let default_export = exports_obj\n        .get(scope, default.into())\n        .ok_or_else(exception_already_thrown)?;\n    if default_export.is_null_or_undefined() {\n        return Ok(None);\n    }\n    let hooks = v2::get_hooks_from_default_export(scope, default_export, exports_obj)?\n        .ok_or_else(|| anyhow::anyhow!(\"default export is not a Schema object\"))?;\n    Ok(Some(hooks))\n}\n\n/// Process the thrown exception value into an `ExecutionError`.\npub(super) fn process_thrown_exception(\n    scope: &mut PinScope<'_, '_>,\n    hooks: &HookFunctions<'_>,\n    exc: Local<'_, v8::Value>,\n) -> ExcResult<Option<ExecutionError>> {\n    match hooks.abi {\n        AbiVersion::V1 => Ok(None),\n        AbiVersion::V2 => v2::process_thrown_exception(scope, hooks, exc),\n    }\n}\n","sourceCodeStart":127,"sourceCodeEnd":160,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/core/src/host/v8/syscall/mod.rs#L127-L160","documentation":"The JS module's default export was found and is neither null nor undefined, but v2::get_hooks_from_default_export could not interpret it as a Schema object — it does not carry the structure ABI-v2 bindings attach to exported schemas. The host therefore cannot extract reducer/table/lifecycle hooks and startup fails. A default export exists, but it is the wrong kind of value.","triggerScenarios":"Default-exporting a plain object, class, or function instead of the generated schema: `export default {}`, `export default MyComponent`, or a schema value produced by a different (older/newer) bindings generation than the host's ABI v2 expects.","commonSituations":"Hand-written entry points exporting the wrong symbol; modules built with bindings whose Schema shape predates ABI v2; refactors where an intermediate builder value is exported instead of the finished schema.","solutions":["Default-export exactly the schema value produced by the generated bindings.","Upgrade or regenerate the JS bindings so the exported object matches the host's ABI v2 expectations.","Add a pre-deploy smoke check that imports the built bundle and validates the default export.","Diff against a freshly scaffolded module to see the expected export shape."],"exampleFix":"// before: default export is not the schema object\nexport default { reducers, tables };\n\n// after: default-export the schema the bindings generate\nconst schema = buildSchema({ reducers, tables });\nexport default schema;","handlingStrategy":"type-guard","validationCode":"// pre-deploy check: the default export must look like the generated Schema\nconst mod = await import('./dist/module.js');\nif (!isSchemaObject(mod.default)) {\n    throw new Error('default export is not a Schema object');\n}","typeGuard":"export function isSchemaObject(v: unknown): v is { reducers: object; tables: object } {\n  return typeof v === 'object' && v !== null && 'reducers' in v && 'tables' in v;\n}","tryCatchPattern":null,"preventionTips":["Export exactly the value the generated bindings produce as default.","Do not hand-roll the default export.","Diff a failing module against a fresh scaffold to spot export-shape drift."],"tags":["v8","javascript","default-export","abi-v2","module-startup"],"backgroundTag":"invalid-module-export","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}