{"record":{"id":"4b2799869f6ef62c","repo":"clockworklabs/SpacetimeDB","slug":"addtable-table-table-name-not-found-in-new-mo","errorCode":null,"errorMessage":"AddTable: table `{table_name}` not found in new module def","messagePattern":"AddTable: table `(.+?)` not found in new module def","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/engine/src/update.rs","lineNumber":289,"sourceCode":"                let table_id = stdb.table_id_from_name_mut(tx, &table_name)?.unwrap();\n\n                if stdb.table_row_count_mut(tx, table_id).unwrap_or(0) > 0 {\n                    anyhow::bail!(\n                        \"Cannot remove table `{table_name}`: table contains data. \\\n                         Clear the table's rows (e.g. via a reducer) before removing it from your schema.\"\n                    );\n                }\n\n                log!(logger, \"Dropping table `{table_name}`\");\n                stdb.drop_table(tx, table_id)?;\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::AddTable(table_name_key) => {\n                let (namespace, local) = table_name_key;\n                let table_name = joined(namespace, local);\n                let (owning_def, table_def) = plan\n                    .new\n                    .find_table(table_name_key)\n                    .ok_or_else(|| anyhow::anyhow!(\"AddTable: table `{table_name}` not found in new module def\"))?;\n                log!(logger, \"Creating table `{table_name}`\");\n                create_table_from_def_with_prefix(stdb, tx, owning_def, table_def, namespace)?;\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::AddView(view_name_key) => {\n                let (namespace, local) = view_name_key;\n                let view_name = joined(namespace, local);\n                let (owning_def, view_def) = plan\n                    .new\n                    .find_view(view_name_key)\n                    .ok_or_else(|| anyhow::anyhow!(\"AddView: view `{view_name}` not found in new module def\"))?;\n                create_table_from_view_def_with_prefix(stdb, tx, owning_def, view_def, namespace)?;\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::RemoveView(view_name_key) => {\n                let (namespace, local) = view_name_key;\n                let view_name = joined(namespace, local);\n                let view_id = stdb\n                    .view_id_from_name_mut(tx, &view_name)?\n                    .ok_or_else(|| anyhow::anyhow!(\"RemoveView: view `{view_name}` not found in database\"))?;","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/engine/src/update.rs#L271-L307","documentation":"Auto-migrate step AddTable: plan.new.find_table(table_name_key) returned None, so the table the plan wants to create is missing from the new module def. The migration plan's steps and the def they were derived from are inconsistent — an internal invariant break, not a user-facing validation error.","triggerScenarios":"A MigratePlan whose steps were computed against a different def than plan.new; namespace/prefix differences making find_table miss the key; a bug in the schema differ emitting an AddTable step for a table it dropped from the def.","commonSituations":"Hand-assembled or cached plans reused across def revisions; upstream diff bugs; submodule tables whose namespaced key changed between plan creation and apply.","solutions":["Regenerate the migration plan from the exact ModuleDef passed as plan.new","Check the failing table key (namespace, local) matches the def's namespacing","Report upstream with both defs if the plan came from the differ"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match auto_migrate_database(&stdb, &mut tx, auth, &plan, &logger) {\n    Err(e) if e.to_string().contains(\"AddTable:\") && e.to_string().contains(\"not found in new module def\") => {\n        // plan/def desync: regenerate the plan from the same def, then retry once\n        let plan2 = MigratePlan::Auto(diff_defs(old_def, new_def)?);\n        auto_migrate_database(&stdb, &mut tx, auth, &plan2, &logger)\n    }\n    r => r,\n}","preventionTips":["Never cache migration plans across def edits","Compute steps and lookups from one def snapshot","Add round-trip tests asserting every emitted step resolves in its def"],"tags":["rust","spacetimedb","migration","table","internal-invariant"],"backgroundTag":"migration-plan-invalid","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"}