clockworklabs/SpacetimeDB · error · Error

Table ${String(name)} does not exist

Error message

Table ${String(name)} does not exist

What it means

ClientCache.getTable(name) looks up a TableCache in the tables map, which is populated only by getOrCreateTable (registerTable/registerTables flows). A miss means the table was never registered on this client before the read, and the SDK logs a console.error with registration guidance before throwing.

Source

Thrown at crates/bindings-typescript/src/sdk/client_cache.ts:102

   * The tables in the database.
   */
  readonly tables = new TableMap<RemoteModule>();

  /**
   * Returns the table with the given name.
   * - If SchemaDef is a concrete schema, `name` is constrained to known table names,
   *   and the return type matches that table.
   * - If SchemaDef is undefined, `name` is string and the return type is untyped.
   */
  getTable<N extends TableName<RemoteModule>>(
    name: N
  ): TableCacheForTableName<RemoteModule, N> {
    const table = this.tables.get(name);
    if (!table) {
      console.error(
        'The table has not been registered for this client. Please register the table before using it. If you have registered global tables using the SpacetimeDBClient.registerTables() or `registerTable()` method, please make sure that is executed first!'
      );
      throw new Error(`Table ${String(name)} does not exist`);
    }
    return table;
  }

  /**
   * Returns the table with the given name, creating it if needed.
   * - Typed mode: `tableTypeInfo.tableName` is constrained to known names and
   *   the return type matches that table.
   * - Untyped mode: accepts any string and returns an untyped TableCache.
   */
  getOrCreateTable<N extends TableName<RemoteModule>>(
    tableDef: TableDefForTableName<RemoteModule, N>
  ): TableCacheForTableName<RemoteModule, N> {
    const name = tableDef.accessorName;

    const table = this.tables.get(name);
    if (table) {
      return table;

View on GitHub (pinned to 524b4487d9)

Solutions

  1. Call SpacetimeDBClient.registerTables(...) at module scope or before the first read/getTable/useTable
  2. Check registration first: if (!db.clientCache.tables.has(name)) register or await registration
  3. Use db.clientCache.getOrCreateTable(tableDef) when you hold the generated table definition
  4. In untyped mode, verify the string exactly matches the generated table's accessorName

Example fix

// before
// registration happens later, in a useEffect
const rows = db.clientCache.getTable('user'); // throws: Table user does not exist

// after
// register at module scope, before any component reads the cache
SpacetimeDBClient.registerTables(User, Post);
const rows = db.clientCache.getTable('user');
Defensive patterns

Strategy: validation

Validate before calling

if (!db.clientCache.tables.has(tableName)) {
  // register before reading, or bail out with your own error
  SpacetimeDBClient.registerTable(TableDefs[tableName]);
}
const table = db.clientCache.getTable(tableName);

Type guard

function tableIsRegistered(db: DbConnection, name: string): boolean {
  return db.clientCache.tables.has(name);
}

Try / catch

try {
  const table = db.clientCache.getTable(name);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Table ') && e.message.endsWith(' does not exist')) {
    // registration race: register, then retry once
  } else throw e;
}

Prevention

When it happens

Trigger: Calling db.clientCache.getTable('user') before SpacetimeDBClient.registerTable(s) ran; a typo'd or renamed table name (especially in untyped mode where name is any string); registering tables in an async effect while a component reads the cache synchronously during render.

Common situations: registerTables called inside React useEffect (runs after first render) while useTable or manual cache access happens during render; stale generated bindings where a table was renamed; a name mismatch between the generated accessor and a hand-typed string.

Related errors


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