{"record":{"id":"b8fe837595db609d","repo":"clockworklabs/SpacetimeDB","slug":"changeindexsourcename-index-name-not-found-in-b8fe83","errorCode":null,"errorMessage":"ChangeIndexSourceName: `{index_name}` not found in new module def","messagePattern":"ChangeIndexSourceName: `(.+?)` not found in new module def","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/engine/src/update.rs","lineNumber":423,"sourceCode":"\n                log!(\n                    logger,\n                    \"Changing column accessor name for `{}`.`{}` to `{}`\",\n                    table_name,\n                    col_name,\n                    new_col_def.accessor_name,\n                );\n                stdb.alter_column_accessor_name(tx, table_id, col_schema.col_pos, new_col_def.accessor_name.clone())?;\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::ChangeIndexSourceName(key) => {\n                let (namespace, index_name) = key;\n                let (_old_owning_def, old_table_def) =\n                    plan.old.find_storing_table(namespace, index_name).ok_or_else(|| {\n                        anyhow::anyhow!(\"ChangeIndexSourceName: `{index_name}` not found in old module def\")\n                    })?;\n                let (_new_owning_def, new_table_def) =\n                    plan.new.find_storing_table(namespace, index_name).ok_or_else(|| {\n                        anyhow::anyhow!(\"ChangeIndexSourceName: `{index_name}` not found in new module def\")\n                    })?;\n                let table_full_name = joined(namespace, &old_table_def.name);\n                let stored_name = namespace.join_raw(&index_name.clone().into());\n                let new_index_def = new_table_def\n                    .indexes\n                    .get(index_name)\n                    .ok_or_else(|| anyhow::anyhow!(\"Index `{index_name}` not found in table `{table_full_name}`\"))?;\n\n                let table_id = stdb.table_id_from_name_mut(tx, &table_full_name)?.unwrap();\n                let table_schema = stdb.schema_for_table_mut(tx, table_id)?;\n                let index_schema = table_schema\n                    .indexes\n                    .iter()\n                    .find(|index| index.index_name == stored_name)\n                    .ok_or_else(|| anyhow::anyhow!(\"Index `{index_name}` not found in table `{table_full_name}`\"))?;\n                let new_source_name = namespace.join_raw(&new_index_def.source_name.clone().into());\n\n                log!(","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/engine/src/update.rs#L405-L441","documentation":"Applying AutoMigrateStep::ChangeIndexSourceName: plan.new.find_storing_table(namespace, index_name) returns None - no table in the NEW module def stores the index, even though the plan claims the index survives with a changed source name. The step's index key does not resolve in the new defs, a plan/def inconsistency. The publish aborts.","triggerScenarios":"Renaming or dropping the index (or its table) in the same publish as the source rename, so the new def no longer contains the index under that key; index-name normalization or accessor-derived naming differences between the def the planner diffed and the def being applied.","commonSituations":"Bundling index renames with column renames in one publish; unpinned #[index(btree)] attribute names that shift when the annotated field is renamed; toolchain version changes between publishes.","solutions":["Clean-rebuild and republish to eliminate def/plan desync.","Split the migration: change the index source in one publish, rename/drop the index in another.","Pin the index name with #[index(name = \"...\")] on both old and new versions.","Align SDK/CLI/server versions with the database's provenance.","Dev: spacetime publish --delete-data <db>.","Report persistent cases as an auto_migrate planner bug."],"exampleFix":"// before: rename the indexed column and the index in one publish\n#[spacetimedb::index(name = \"by_level\", btree)] // was `by_hp` on field `hp` -> `level`\n\n// after: two publishes\n// 1) #[spacetimedb::column(name = \"hp\")] + #[spacetimedb::index(name = \"by_hp\", btree)] pub level: u32;\n// 2) rename the index alone","handlingStrategy":"validation","validationCode":"use spacetimedb_schema::auto_migrate::AutoMigrateStep;\nfor step in &plan.steps {\n    if let AutoMigrateStep::ChangeIndexSourceName((namespace, index_name)) = step {\n        if plan.new.find_storing_table(namespace, index_name).is_none() {\n            anyhow::bail!(\"new def lacks index {} - plan/def desync\", index_name);\n        }\n    }\n}","typeGuard":"fn index_in_new_def<'a>(plan: &'a AutoMigratePlan, ns: &str, idx: &str) -> bool {\n    plan.new.find_storing_table(ns, idx).is_some()\n}","tryCatchPattern":"match update_database(&stdb, tx, &plan, ...).await {\n    Err(e) if e.to_string().contains(\"ChangeIndexSourceName\")\n        && e.to_string().contains(\"new module def\") => {\n        // Split publishes: source rename first, index rename/drop in a later publish.\n    }\n    result => result?,\n}","preventionTips":["Pin index names and the columns they cover.","One index-related change per publish.","Keep toolchain versions aligned between builds.","Clean-rebuild before republishing after SDK updates."],"tags":["spacetimedb","rust","schema-migration","index-rename","publish"],"backgroundTag":"schema-migration-plan-mismatch","analyzedSha":"6dee26c6efc2856793e12b148a59742964f5d783","analyzedAt":"2026-08-20T06:08:37.179Z","contentChangedAt":"2026-08-20T06:08:37.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}