clockworklabs/SpacetimeDB · error · TypeError

There is already a reducer, procedure, or view with the name

Error message

There is already a reducer, procedure, or view with the name '${name}'

What it means

SchemaInner.defineFunction guards a single shared namespace: reducers, procedures, and views may not share a name within a module (submodules are flattened into one dispatch table, so their function names also collide). Registering a second function with an existing name throws a TypeError during schema construction, before the module can build or deploy.

Source

Thrown at crates/bindings-typescript/src/server/schema.ts:124

   * Maps reducer/procedure export objects to their source names.
   * Used for resolving scheduled table targets.
   */
  functionExports: Map<UntypedScheduledFunctionExport, string> = new Map();
  tableSourceNames: Map<UntypedTableSchema, string[]> = new Map();
  httpHandlerExports: Map<HttpHandlerExport<UntypedSchemaDef>, string> =
    new Map();
  pendingSchedules: PendingSchedule[] = [];
  pendingHttpRoutes: PendingHttpRoute[] = [];
  submoduleDispatchInfos: SubmoduleDispatchInfo[] = [];

  constructor(getSchemaType: (ctx: SchemaInner<S>) => S) {
    super();
    this.schemaType = getSchemaType(this);
  }

  defineFunction(name: string) {
    if (this.existingFunctions.has(name)) {
      throw new TypeError(
        `There is already a reducer, procedure, or view with the name '${name}'`
      );
    }
    this.existingFunctions.add(name);
  }

  defineHttpHandler(name: string) {
    if (this.existingHttpHandlers.has(name)) {
      throw new TypeError(
        `There is already an HTTP handler with the name '${name}'`
      );
    }
    this.existingHttpHandlers.add(name);
  }

  resolveSchedules() {
    if (this.schedulesResolved) {
      return;

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Rename one of the colliding functions so every reducer/procedure/view name is unique module-wide
  2. If submodules collide, rename inside one submodule or lean on its namespace/name prefix so flattened names differ
  3. Search the whole module (including all submodules) for the name in the error message to locate both definitions

Example fix

// before
function leaderboard() {} // reducer
function leaderboard() {} // view -> TypeError at schema build

// after
function leaderboard() {} // reducer
function leaderboardView() {} // view
Defensive patterns

Strategy: validation

Validate before calling

// during module build, guard the shared reducer/procedure/view namespace:
const seen = new Set<string>();
function checkFunctionName(name: string): void {
  if (seen.has(name)) throw new Error(`duplicate function name: ${name}`);
  seen.add(name);
}
// call for every reducer, procedure, and view (including submodules)

Prevention

When it happens

Trigger: Two reducers with the same name; a view named the same as a reducer or procedure (e.g. both called `leaderboard`); two submodules that each export a function with a common name like `init` or `update` and get flattened together.

Common situations: Copy-pasted reducers renamed at call sites but not in their definitions; merging submodules with overlapping generic names; refactoring a view into a procedure while keeping the old view.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/d83690c7dd80c42f. Report an issue: GitHub.