{"record":{"id":"26ec7e36aa46b93a","repo":"clockworklabs/SpacetimeDB","slug":"http-handler-exportname-was-exported-more-tha","errorCode":null,"errorMessage":"HTTP handler '${exportName}' was exported more than once","messagePattern":"HTTP handler '(.+?)' was exported more than once","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/server/http_handlers.ts","lineNumber":373,"sourceCode":"      throw new TypeError(`Route conflict for \\`${path}\\``);\n    }\n    return new Router([...this.#routes, candidate]);\n  }\n}\n\nexport function makeHttpHandlerExport<S extends UntypedSchemaDef>(\n  ctx: SchemaInner,\n  opts: HttpHandlerOpts | undefined,\n  fn: HandlerFn<S>\n): HttpHandlerExport<S> {\n  const handlerExport: HttpHandlerExport<S> = Object.assign(\n    (...args: Parameters<HandlerFn<S>>) => fn(...args),\n    {\n      [httpHandlerFn]: fn,\n      [exportContext]: ctx,\n      [registerExport](ctx: SchemaInner, exportName: string) {\n        if (exportedHttpHandlerObjects.has(handlerExport)) {\n          throw new TypeError(\n            `HTTP handler '${exportName}' was exported more than once`\n          );\n        }\n        exportedHttpHandlerObjects.add(handlerExport);\n        registerHttpHandler(ctx, exportName, fn, opts);\n        ctx.httpHandlerExports.set(\n          handlerExport as HttpHandlerExport<UntypedSchemaDef>,\n          exportName\n        );\n      },\n    }\n  );\n  return handlerExport;\n}\n\nexport function makeHttpRouterExport(\n  ctx: SchemaInner,\n  router: Router","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/bindings-typescript/src/server/http_handlers.ts#L355-L391","documentation":"HTTP handlers are created via makeHttpHandlerExport and must be registered exactly once when the module's exports are processed. Each handler object is tracked in the module-level exportedHttpHandlerObjects WeakSet; if the same handler object is registered again under another export name, the SDK throws, because one handler object must map to exactly one export name and schema entry.","triggerScenarios":"Exporting the same handler object under two names (including via barrel-file re-exports or aliases); registering one handler object in two submodules; dev-server hot reload re-running export registration on the same objects.","commonSituations":"index.ts doing `export * from './users'` plus `export { getUser as getUser2 } from './users'`; sharing a handler constant between submodules to avoid duplication; bundlers that instantiate module code twice.","solutions":["Create a separate handler per export name with its own httpHandler/makeHttpHandlerExport call instead of re-exporting the same object","Remove the redundant re-export so each handler is exported from exactly one module under exactly one name","If hot-module-reload triggers it during development, restart the dev server so the export table is rebuilt once"],"exampleFix":"// before\n// users.ts\nexport const getUser = makeHttpHandler(...);\n// index.ts\nexport { getUser } from './users';\nexport { getUser as getUserV2 } from './users'; // second registration throws\n\n// after: one handler object per export name\nexport { getUser } from './users';\nexport const getUserV2 = makeHttpHandler(/* own fn */);","handlingStrategy":"validation","validationCode":"// convention check at module setup: one export name per handler object\nconst registered = new WeakSet<object>();\nfunction assertSingleExport(handlerObj: object, name: string): void {\n  if (registered.has(handlerObj)) throw new Error(`handler re-exported: ${name}`);\n  registered.add(handlerObj);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create one handler object per export name; never re-export or alias handler objects","Keep barrel files from re-exporting the same handler under multiple names","Restart dev servers after schema/export changes so registration tables are rebuilt cleanly"],"tags":["http","module-build","exports","typescript"],"backgroundTag":"duplicate-export","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}