clockworklabs/SpacetimeDB · error
AddIndex: index `{index_name}` not found in new module def
Error message
AddIndex: index `{index_name}` not found in new module def What it means
Auto-migrate step AddIndex: the storing table was found, but plan.new.lookup(key) returned None for the IndexDef itself. The index key resolves to a table yet the def's index map has no entry — plan and def disagree, an internal invariant break.
Source
Thrown at crates/engine/src/update.rs:327
}
spacetimedb_schema::auto_migrate::AutoMigrateStep::UpdateView(_) => {
// if we already have to disconnect clients, no need to set
// `EvaluateSubscribedViews` as clients will be disconnected anyway
if !matches!(res, UpdateResult::RequiresClientDisconnect) {
res = UpdateResult::EvaluateSubscribedViews;
}
}
spacetimedb_schema::auto_migrate::AutoMigrateStep::AddIndex(key) => {
let (namespace, index_name) = key;
let (owning_def, table_def) = plan
.new
.find_storing_table(namespace, index_name)
.ok_or_else(|| anyhow::anyhow!("AddIndex: `{index_name}` not found in new module def"))?;
let table_full_name = joined(namespace, &table_def.name);
let index_def: &IndexDef = plan
.new
.lookup(key)
.ok_or_else(|| anyhow::anyhow!("AddIndex: index `{index_name}` not found in new module def"))?;
let table_id = stdb.table_id_from_name_mut(tx, &table_full_name)?.unwrap();
let index_cols = ColSet::from(index_def.algorithm.columns());
let is_unique = table_def
.constraints
.iter()
.filter_map(|(_, c)| c.data.unique_columns())
.any(|unique_cols| unique_cols == &index_cols);
log!(logger, "Creating index `{index_name}` on table `{table_full_name}`");
let mut index_schema = IndexSchema::from_module_def(owning_def, index_def, table_id, 0.into());
// Apply namespace prefix for submodule indexes
index_schema.index_name = namespace.join_raw(&index_schema.index_name);
index_schema.alias = index_schema.alias.as_ref().map(|alias| namespace.join_raw(alias));
View on GitHub (pinned to 6dee26c6ef)
Solutions
- Rebuild plan and plan.new from a single consistent ModuleDef
- Never mix keys from one def with lookups into another
- Report upstream with the key if machine-generated
Defensive patterns
Strategy: try-catch
Try / catch
match auto_migrate_database(&stdb, &mut tx, auth, &plan, &logger) {
Err(e) if e.to_string().contains("index") && e.to_string().contains("not found in new module def") => {
// storing table resolved but IndexDef missing: rebuild plan from a single def, retry once
let plan2 = MigratePlan::Auto(diff_defs(old_def, new_def)?);
auto_migrate_database(&stdb, &mut tx, auth, &plan2, &logger)
}
r => r,
} Prevention
- Never mix keys from one def with lookup maps of another
- Do not edit defs between plan computation and application
- File upstream bugs with the failing (namespace, index) key
When it happens
Trigger: A def revision where the index was removed after the step list was computed; hand-assembled plans mixing key sets and def maps; differ bug leaving the storing-table edge without the index definition.
Common situations: Manual plan construction; schema crate version skew; tests mutating defs between diff and apply.
Related errors
- AddIndex: `{index_name}` not found in new module def
- RemoveIndex: `{index_name}` not found in old module def
- Precheck: sequence `{sequence_name}` not found in new module
- AddTable: table `{table_name}` not found in new module def
- AddView: view `{view_name}` not found in new module def
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/c894652d46596574.
Report an issue: GitHub.