{"record":{"id":"485fb9800d40ad98","repo":"clockworklabs/SpacetimeDB","slug":"submodules-cannot-declare-environment-variables","errorCode":null,"errorMessage":"Submodules cannot declare environment variables","messagePattern":"Submodules cannot declare environment variables","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/server/schema.ts","lineNumber":327,"sourceCode":"    });\n    this.#ctx.resolveSchedules();\n    return this.#ctx.rawModuleDefV10();\n  }\n\n  /**\n   * @internal – called by schema() when processing a submodule namespace entry.\n   * Registers the library's exports and returns both the serialized module def\n   * and the runtime dispatch info needed by ModuleHooksImpl for __call_reducer__.\n   */\n  buildSubmoduleDispatch(exports: object): {\n    rawDef: RawModuleDefV10;\n    dispatch: SubmoduleDispatchInfo;\n  } {\n    const rawDef = this.buildRawModuleDefV10(exports, {\n      ignoreNonModuleExports: true,\n    });\n    if (this.#ctx.moduleDef.environment.length !== 0) {\n      throw new TypeError('Submodules cannot declare environment variables');\n    }\n    this.#ctx.resolveHttpRoutes();\n    return {\n      rawDef,\n      dispatch: {\n        namespace: '',\n        reducerFns: [...this.#ctx.reducers],\n        reducerDefs: [...this.#ctx.moduleDef.reducers],\n        procedureFns: [...this.#ctx.procedures],\n        procedureDefs: [...this.#ctx.moduleDef.procedures],\n        anonViewFns: [...this.#ctx.anonViews],\n        viewFns: [...this.#ctx.views],\n        typespace: this.#ctx.moduleDef.typespace,\n        tables: Object.values(this.#ctx.schemaType.tables).map(t => ({\n          accessorName: t.accessorName,\n          tableDef: t.tableDef,\n        })),\n        schemaTables: this.#ctx.schemaType.tables,","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/eddf9f5014579a50d4b67630e28b6e15cad9c4af/crates/bindings-typescript/src/server/schema.ts#L309-L345","documentation":"Submodule builds (buildSubmoduleDispatch) require the module definition to have an empty environment table. Environment variables are a top-level module concern; allowing them in submodules would create ambiguous ownership of runtime environment keys, so a TypeError is thrown when this.#ctx.moduleDef.environment is non-empty.","triggerScenarios":"Calling buildSubmoduleDispatch (or the submodule build path it drives, e.g. buildRawModuleDefV10 with ignoreNonModuleExports) on a context whose moduleDef.environment has entries registered.","commonSituations":"Refactoring a monolithic module into submodules while leaving its env declarations in place; adding env vars inside a submodule export file.","solutions":["Move environment declarations to the top-level module definition","Remove env declarations from the submodule's exports","Restructure so each submodule builds a clean moduleDef with no environment entries"],"exampleFix":"// before\n// submodule.ts\nexport const env = ctx.env('KEY', str);\n// after\n// main.ts (top-level module)\nexport const env = ctx.env('KEY', str); // submodule stays env-free","handlingStrategy":"validation","validationCode":"if (this.#ctx.moduleDef.environment.length !== 0) {\n  throw new TypeError('Refusing to build submodule: environment declarations must live at the top level');\n}","typeGuard":null,"tryCatchPattern":"try {\n  buildSubmoduleDispatch.call(builder, exports);\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('environment variables')) {\n    console.error('Move env declarations from the submodule to the top-level module');\n  } else throw e;\n}","preventionTips":["Keep all ctx.env calls in the top-level module file","Add a build-time check that submodule files export no env vars","Document the env-ownership rule for submodule authors"],"tags":["submodule","environment","schema","typescript"],"backgroundTag":"unsupported-operation","analyzedSha":"eddf9f5014579a50d4b67630e28b6e15cad9c4af","analyzedAt":"2026-09-20T12:15:59.611Z","contentChangedAt":"2026-09-20T12:15:59.611Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}