{"record":{"id":"0ec09b01e23b6b58","repo":"clockworklabs/SpacetimeDB","slug":"addcolumns-table-table-name-not-found-in-new","errorCode":null,"errorMessage":"AddColumns: table `{table_name}` not found in new module def","messagePattern":"AddColumns: table `(.+?)` not found in new module def","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/engine/src/update.rs","lineNumber":618,"sourceCode":"                log!(logger, \"Adding row-level security `{sql_rls}`\");\n                let rls = plan.new.lookup::<RawRowLevelSecurityDefV9>(sql_rls).ok_or_else(|| {\n                    anyhow::anyhow!(\"AddRowLevelSecurity: RLS `{sql_rls}` not found in new module def\")\n                })?;\n                let rls = RowLevelExpr::build_row_level_expr(tx, &auth_ctx, rls)?;\n\n                stdb.create_row_level_security(tx, rls.def)?;\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::RemoveRowLevelSecurity(sql_rls) => {\n                log!(logger, \"Removing row-level security `{sql_rls}`\");\n                stdb.drop_row_level_security(tx, sql_rls.clone())?;\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::AddColumns(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!(\"AddColumns: table `{table_name}` not found in new module def\"))?;\n                let table_id = stdb.table_id_from_name_mut(tx, &table_name).unwrap().unwrap();\n                let column_schemas = column_schemas_from_defs(owning_def, &table_def.columns, table_id);\n\n                let default_values: Vec<AlgebraicValue> = table_def\n                    .columns\n                    .iter()\n                    .filter_map(|col_def| col_def.default_value.clone())\n                    .collect();\n                stdb.add_columns_to_table_mut_tx(tx, table_id, column_schemas, default_values)?;\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::DisconnectAllUsers => {\n                log!(logger, \"Disconnecting all users\");\n                // It does not disconnect clients right away,\n                // but send response indicated that caller should drop clients\n                res = UpdateResult::RequiresClientDisconnect;\n            }\n        }\n    }","sourceCodeStart":600,"sourceCodeEnd":636,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/engine/src/update.rs#L600-L636","documentation":"Applying AddColumns, which adds columns to an existing table: plan.new.find_table fails, so neither the column schemas nor their default values can be built. The add-columns step references a table key absent from the new module def - plan/def desync. The publish aborts before any column is added.","triggerScenarios":"Adding columns while renaming, moving, or deleting the table in the same publish; or the def set being applied differs from the one the planner diffed (stale build artifacts, mismatched compiler/SDK versions).","commonSituations":"Feature branches combining new fields with table renames; CI publishing with a different toolchain than the one that published the database; incremental builds after SDK upgrades.","solutions":["Clean-rebuild and republish.","Add the columns in their own publish with the table name and location unchanged.","Pin the stored name with #[table(name = \"...\")] and keep it stable.","Align SDK/CLI/server versions with the live database's provenance.","Dev: spacetime publish --delete-data <db>.","Report as a planner bug if a clean split publish still triggers it."],"exampleFix":"// before: add a column AND rename the table in one publish\n#[spacetimedb::table(name = \"members\")] // was `players`\npub struct Member { pub level: u32 /* new */ }\n\n// after: two publishes\n// 1) #[spacetimedb::table(name = \"players\")] struct Player { pub level: u32 }\n// 2) rename the table separately","handlingStrategy":"validation","validationCode":"use spacetimedb_schema::auto_migrate::AutoMigrateStep;\nfor step in &plan.steps {\n    if let AutoMigrateStep::AddColumns(key) = step {\n        if plan.new.find_table(key).is_none() {\n            anyhow::bail!(\"AddColumns step references table {:?} missing from new def\", key);\n        }\n    }\n}","typeGuard":"fn table_in_new_def(plan: &AutoMigratePlan, key: (&str, &str)) -> bool {\n    plan.new.find_table(key).is_some()\n}","tryCatchPattern":"match update_database(&stdb, tx, &plan, ...).await {\n    Err(e) if e.to_string().contains(\"AddColumns\")\n        && e.to_string().contains(\"not found in new module def\") => {\n        // Split: add columns with a stable table name; rename/move the table afterwards.\n    }\n    result => result?,\n}","preventionTips":["Add columns in a publish where the table's name and location are unchanged.","Pin table names with #[table(name = \"...\")] before evolving the schema.","Provide default values for new columns where the SDK supports it.","One logical schema change per publish; clean-build after toolchain upgrades."],"tags":["spacetimedb","rust","schema-migration","add-column","publish","table-rename"],"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"}