{"record":{"id":"030a640f1b13c086","repo":"clockworklabs/SpacetimeDB","slug":"tableid-table-id-does-not-exist","errorCode":null,"errorMessage":"TableId `{table_id}` does not exist","messagePattern":"TableId `(.+?)` does not exist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/datastore/src/locking_tx_datastore/tx.rs","lineNumber":61,"sourceCode":"        = IndexScanRangeIter<'a>\n    where\n        Self: 'a;\n\n    type PointIndexIter<'a>\n        = IndexScanPointIter<'a>\n    where\n        Self: 'a;\n\n    fn row_count(&self, table_id: TableId) -> u64 {\n        self.committed_state_shared_lock\n            .table_row_count(table_id)\n            .unwrap_or_default()\n    }\n\n    fn table_scan<'a>(&'a self, table_id: TableId) -> anyhow::Result<Self::TableIter<'a>> {\n        self.committed_state_shared_lock\n            .table_scan(table_id)\n            .ok_or_else(|| anyhow::anyhow!(\"TableId `{table_id}` does not exist\"))\n    }\n\n    fn index_scan_range<'a>(\n        &'a self,\n        table_id: TableId,\n        index_id: IndexId,\n        range: &impl RangeBounds<AlgebraicValue>,\n    ) -> anyhow::Result<Self::RangeIndexIter<'a>> {\n        self.with_index(table_id, index_id, |i| i.seek_range_via_algebraic_value(range))?\n            .map_err(|IndexCannotSeekRange| IndexError::IndexCannotSeekRange(index_id).into())\n    }\n\n    fn index_scan_point<'a>(\n        &'a self,\n        table_id: TableId,\n        index_id: IndexId,\n        point: &AlgebraicValue,\n    ) -> anyhow::Result<Self::PointIndexIter<'a>> {","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/datastore/src/locking_tx_datastore/tx.rs#L43-L79","documentation":"A read-only transaction (TxId) called table_scan for a TableId the committed state does not know. TableIds are numeric ids assigned at table creation; this one was never created, was dropped, or belongs to an older schema generation — committed_state_shared_lock has no entry for it, so the scan cannot even start.","triggerScenarios":"Scanning with a TableId captured before a module update dropped or recreated the table; query or subscription plans compiled against a previous schema and replayed after it changed; passing TableId::SENTINEL or an id invented by the caller.","commonSituations":"Hot module updates where old clients hold compiled plans; internal code caching table ids across schema changes; tools reading table ids from stale metadata files.","solutions":["Resolve the table name to its current TableId (schema_for_table or iterating st_table) before scanning","Refresh query/subscription plans after schema changes instead of reusing compiled ids","Handle the error by re-planning or re-subscribing rather than retrying the same id","Check that the table actually exists in this database/replica"],"exampleFix":"// before: scan with a TableId cached before a module update\nlet iter = tx.table_scan(cached_table_id)?;\n\n// after: resolve the id from the current schema by name first\nlet schema = committed_state.schema_for_table_by_name(table_name)?;\nlet iter = tx.table_scan(schema.table_id)?;","handlingStrategy":"validation","validationCode":"// Resolve the id from the live schema before scanning\nfn resolve_table_id(tx: &TxId, name: &str) -> anyhow::Result<TableId> {\n    tx.schema_for_table_by_name(name)\n        .map(|s| s.table_id)\n        .ok_or_else(|| anyhow::anyhow!(\"table {name} does not exist\"))\n}","typeGuard":null,"tryCatchPattern":"On this error, treat the TableId as stale: re-resolve by name from the current schema; if the table was dropped, invalidate cached plans and re-subscribe instead of retrying the same id.","preventionTips":["Never cache TableIds across module updates; resolve by name per session and refresh on schema-change notifications","Recompile query/subscription plans whenever the module schema version changes","Reject fabricated or SENTINEL ids at the API boundary with a clear message"],"tags":["rust","spacetimedb","datastore","table-id","read-transaction"],"backgroundTag":"table-not-found","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}