{"record":{"id":"d20ba1e35f3eaada","repo":"clockworklabs/SpacetimeDB","slug":"removing-schedules-is-not-yet-implemented","errorCode":null,"errorMessage":"Removing schedules is not yet implemented","messagePattern":"Removing schedules is not yet implemented","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/engine/src/update.rs","lineNumber":597,"sourceCode":"                        TableAccess::Private\n                    }\n                };\n                stdb.alter_table_access(tx, &table_name, access.into())?;\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::ChangePrimaryKey(table_name_key) => {\n                let (namespace, local) = table_name_key;\n                let table_name = joined(namespace, local);\n                let (_owning_def, table_def) = plan.new.find_table(table_name_key).ok_or_else(|| {\n                    anyhow::anyhow!(\"ChangePrimaryKey: table `{table_name}` not found in new module def\")\n                })?;\n                log!(logger, \"Changing primary key for table `{table_name}`\");\n                stdb.alter_table_primary_key(tx, &table_name, table_def.primary_key)?;\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::AddSchedule(_) => {\n                anyhow::bail!(\"Adding schedules is not yet implemented\");\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::RemoveSchedule(_) => {\n                anyhow::bail!(\"Removing schedules is not yet implemented\");\n            }\n            spacetimedb_schema::auto_migrate::AutoMigrateStep::AddRowLevelSecurity(sql_rls) => {\n                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","sourceCodeStart":579,"sourceCodeEnd":615,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/6dee26c6efc2856793e12b148a59742964f5d783/crates/engine/src/update.rs#L579-L615","documentation":"The mirror of AddSchedule: when the new module removes a scheduled reducer that existed in the previous version, the auto-migrator emits AutoMigrateStep::RemoveSchedule, whose handler is explicitly unimplemented and bails. Any publish that drops a schedule aborts the migration.","triggerScenarios":"Publishing a module version that deletes or comments out a #[spacetimedb::scheduled] reducer/schedule table that the previously published version had.","commonSituations":"Removing a periodic cleanup job from a deployed module; refactoring scheduled logic away; disabling a tick reducer during debugging and republishing.","solutions":["In development, delete and republish the database so the schedule is absent from the initial schema (spacetime delete <db> && spacetime publish <db>).","Keep the schedule declared but make the reducer a no-op (early return) so the schema diff contains no RemoveSchedule step.","For data-preserving changes, write a manual migration with spacetime migrate instead of relying on auto-migrate."],"exampleFix":"// before: deleting the scheduled reducer triggers RemoveSchedule\n// (remove `#[spacetimedb::scheduled(reducer = every_10s)] pub struct Tick;`)\nspacetime publish my-db // fails\n\n// after: neutralize the schedule instead of removing it\n#[spacetimedb::scheduled(reducer = every_10s)]\npub struct Tick;\n\n#[spacetimedb::reducer]\nfn every_10s(_ctx: &ReducerContext, _tick: Tick) {\n    // intentionally disabled\n}","handlingStrategy":"fallback","validationCode":"# before publishing, check whether the diff removes a scheduled reducer:\ngit diff HEAD~1 -- module/ | grep -E '^\\-.*spacetimedb::scheduled'\n# a removed schedule means auto-migrate will bail","typeGuard":null,"tryCatchPattern":"match publish(&db, &module).await {\n    Err(e) if e.to_string().contains(\"Removing schedules is not yet implemented\") => {\n        // keep the schedule declared with a no-op reducer, or recreate the db\n    }\n    other => other,\n}","preventionTips":["Disable scheduled reducers by making them no-ops instead of deleting their declarations.","Plan schedule removals as recreate-and-republish events with data export/import.","Track which module versions declared schedules so migration expectations are explicit."],"tags":["migration","schedules","scheduled-reducers","not-implemented","auto-migrate"],"backgroundTag":"unsupported-migration-step","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"}