clockworklabs/SpacetimeDB · error
IndexId `{index_id}` does not exist
Error message
IndexId `{index_id}` does not exist What it means
TxId::with_index found the table but get_index_by_id_with_table returned None: no index with the given IndexId is attached to that table. The index was dropped, belongs to a different table, or has not been created yet (e.g. its creation is still a pending schema change).
Source
Thrown at crates/datastore/src/locking_tx_datastore/tx.rs:141
self.committed_state_shared_lock.iter_by_col_eq(table_id, cols, value)
}
}
impl TxId {
fn with_index<'a, R>(
&'a self,
table_id: TableId,
index_id: IndexId,
seek: impl FnOnce(TableAndIndex<'a>) -> R,
) -> anyhow::Result<R> {
self.committed_state_shared_lock
.get_table(table_id)
.ok_or_else(|| anyhow::anyhow!("TableId `{table_id}` does not exist"))
.and_then(|table| {
table
.get_index_by_id_with_table(&self.committed_state_shared_lock.blob_store, index_id)
.map(seek)
.ok_or_else(|| anyhow::anyhow!("IndexId `{index_id}` does not exist"))
})
}
/// Release this read-only transaction,
/// allowing new mutable transactions to start if this was the last read-only transaction.
///
/// Returns:
/// - [`TxOffset`], the smallest transaction offset visible to this transaction.
/// - [`TxMetrics`], various measurements of the work performed by this transaction.
/// - `ReducerName`, the name of the reducer which ran within this transaction.
pub(super) fn release(self) -> (TxOffset, TxMetrics, Option<ReducerName>) {
// A read tx doesn't consume `next_tx_offset`, so subtract one to obtain
// the offset that was visible to the transaction.
//
// Note that technically the tx could have run against an empty database,
// in which case we'd wrongly return zero (a non-existent transaction).
// This doesn not happen in practice, however, as [RelationalDB::set_initialized]
// creates a transaction.View on GitHub (pinned to 6dee26c6ef)
Solutions
- Look the index up by name via the current schema and use the resolved IndexId
- Re-compile query plans after any module or schema update
- Guard index usage with a startup schema check (iterate st_indexes or get_index_by_name)
- Confirm the index-creating transaction actually committed
Example fix
// before: hardcoded IndexId from an earlier schema generation
let iter = tx.index_scan_range(table_id, hardcoded_index_id, &range)?;
// after: resolve the IndexId by name at startup
let index_id = tx.index_id_by_name(table_id, index_name)?.expect("index exists");
let iter = tx.index_scan_range(table_id, index_id, &range)?; Defensive patterns
Strategy: validation
Validate before calling
// Resolve the index by name at startup instead of trusting a stored IndexId
fn resolve_index_id(tx: &TxId, table_id: TableId, index_name: &str) -> Option<IndexId> {
tx.committed_state_shared_lock
.get_table(table_id)?
.get_index_by_name(index_name)
.map(|(_, idx)| idx.index_id)
} Try / catch
Catch the missing-index error, re-resolve the index by name from the current schema, recompile the plan, and retry once; if the index was dropped, fall back to a table scan or re-subscribe after schema refresh.
Prevention
- Do not persist IndexIds — persist index names and resolve them at startup
- Drop or rebuild cached plans whenever the module's index set changes
- When adding an index, wait for the schema change to commit before routing queries to it
When it happens
Trigger: Index scans using an IndexId captured before the index was dropped or recreated; querying an index that exists only in a newer module version than the database runs; mixing up ids between tables; scanning an index whose creation transaction has not committed.
Common situations: Module updates dropping indexes while old plans cache IndexIds; replicas lagging behind the coordinator's schema; developer tools hardcoding index ids; race between schema change and readers.
Related errors
- TableId `{table_id}` does not exist
- Unique constraint violation during merge: {violation:?}
- cannot serialize refs without a typespace
- unexpected error from `datastore_index_scan_point_bsatn`: {e
- unexpected error from `datastore_index_scan_range_bsatn`: {e
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/dbe8f932383cbd35.
Report an issue: GitHub.