{"record":{"id":"f077e4cac903108e","repo":"clockworklabs/SpacetimeDB","slug":"table-string-name-does-not-exist","errorCode":null,"errorMessage":"Table ${String(name)} does not exist","messagePattern":"Table (.+?) does not exist","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/bindings-typescript/src/sdk/client_cache.ts","lineNumber":102,"sourceCode":"   * The tables in the database.\n   */\n  readonly tables = new TableMap<RemoteModule>();\n\n  /**\n   * Returns the table with the given name.\n   * - If SchemaDef is a concrete schema, `name` is constrained to known table names,\n   *   and the return type matches that table.\n   * - If SchemaDef is undefined, `name` is string and the return type is untyped.\n   */\n  getTable<N extends TableName<RemoteModule>>(\n    name: N\n  ): TableCacheForTableName<RemoteModule, N> {\n    const table = this.tables.get(name);\n    if (!table) {\n      console.error(\n        '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!'\n      );\n      throw new Error(`Table ${String(name)} does not exist`);\n    }\n    return table;\n  }\n\n  /**\n   * Returns the table with the given name, creating it if needed.\n   * - Typed mode: `tableTypeInfo.tableName` is constrained to known names and\n   *   the return type matches that table.\n   * - Untyped mode: accepts any string and returns an untyped TableCache.\n   */\n  getOrCreateTable<N extends TableName<RemoteModule>>(\n    tableDef: TableDefForTableName<RemoteModule, N>\n  ): TableCacheForTableName<RemoteModule, N> {\n    const name = tableDef.accessorName;\n\n    const table = this.tables.get(name);\n    if (table) {\n      return table;","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/bindings-typescript/src/sdk/client_cache.ts#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Call SpacetimeDBClient.registerTables(...) at module scope or before the first read/getTable/useTable","Check registration first: if (!db.clientCache.tables.has(name)) register or await registration","Use db.clientCache.getOrCreateTable(tableDef) when you hold the generated table definition","In untyped mode, verify the string exactly matches the generated table's accessorName"],"exampleFix":"// before\n// registration happens later, in a useEffect\nconst rows = db.clientCache.getTable('user'); // throws: Table user does not exist\n\n// after\n// register at module scope, before any component reads the cache\nSpacetimeDBClient.registerTables(User, Post);\nconst rows = db.clientCache.getTable('user');","handlingStrategy":"validation","validationCode":"if (!db.clientCache.tables.has(tableName)) {\n  // register before reading, or bail out with your own error\n  SpacetimeDBClient.registerTable(TableDefs[tableName]);\n}\nconst table = db.clientCache.getTable(tableName);","typeGuard":"function tableIsRegistered(db: DbConnection, name: string): boolean {\n  return db.clientCache.tables.has(name);\n}","tryCatchPattern":"try {\n  const table = db.clientCache.getTable(name);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Table ') && e.message.endsWith(' does not exist')) {\n    // registration race: register, then retry once\n  } else throw e;\n}","preventionTips":["Register tables at module scope or before the first render that reads them","Avoid registering in useEffect when components read the cache during render","In untyped mode, derive names from the generated table defs instead of typing strings"],"tags":["table","cache","registration","typescript"],"backgroundTag":"table-not-registered","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}