clockworklabs/SpacetimeDB · error · anyhow::Error
Adding schedules is not yet implemented
Error message
Adding schedules is not yet implemented
What it means
Auto-migration plans contain an AutoMigrateStep::AddSchedule when the new module introduces a scheduled reducer. The engine handler for this step is deliberately unimplemented (anyhow::bail), so any publish whose diff adds a new schedule fails the migration instead of proceeding.
Source
Thrown at crates/engine/src/update.rs:594
if view_def.is_public {
TableAccess::Public
} else {
TableAccess::Private
}
};
stdb.alter_table_access(tx, &table_name, access.into())?;
}
spacetimedb_schema::auto_migrate::AutoMigrateStep::ChangePrimaryKey(table_name_key) => {
let (namespace, local) = table_name_key;
let table_name = joined(namespace, local);
let (_owning_def, table_def) = plan.new.find_table(table_name_key).ok_or_else(|| {
anyhow::anyhow!("ChangePrimaryKey: table `{table_name}` not found in new module def")
})?;
log!(logger, "Changing primary key for table `{table_name}`");
stdb.alter_table_primary_key(tx, &table_name, table_def.primary_key)?;
}
spacetimedb_schema::auto_migrate::AutoMigrateStep::AddSchedule(_) => {
anyhow::bail!("Adding schedules is not yet implemented");
}
spacetimedb_schema::auto_migrate::AutoMigrateStep::RemoveSchedule(_) => {
anyhow::bail!("Removing schedules is not yet implemented");
}
spacetimedb_schema::auto_migrate::AutoMigrateStep::AddRowLevelSecurity(sql_rls) => {
log!(logger, "Adding row-level security `{sql_rls}`");
let rls = plan.new.lookup::<RawRowLevelSecurityDefV9>(sql_rls).ok_or_else(|| {
anyhow::anyhow!("AddRowLevelSecurity: RLS `{sql_rls}` not found in new module def")
})?;
let rls = RowLevelExpr::build_row_level_expr(tx, &auth_ctx, rls)?;
stdb.create_row_level_security(tx, rls.def)?;
}
spacetimedb_schema::auto_migrate::AutoMigrateStep::RemoveRowLevelSecurity(sql_rls) => {
log!(logger, "Removing row-level security `{sql_rls}`");
stdb.drop_row_level_security(tx, sql_rls.clone())?;
}
spacetimedb_schema::auto_migrate::AutoMigrateStep::AddColumns(table_name_key) => {View on GitHub (pinned to 6dee26c6ef)
Solutions
- In development, delete and republish the database (spacetime delete <db> && spacetime publish <db>) so the schedule is created with the initial schema rather than migrated in.
- For databases that must retain data, author a manual migration (spacetime migrate) that handles the schedule change outside the auto-migrator.
- Defer adding the scheduled reducer until a maintenance window where recreate-and-republish (with a data export/import if needed) is acceptable.
Example fix
// before: adding a scheduled reducer to a live module triggers AddSchedule #[spacetimedb::scheduled(reducer = every_10s)] pub struct Tick; spacetime publish my-db // fails // after (dev): recreate the database so the schedule ships with the initial publish spacetime delete my-db spacetime publish my-db
Defensive patterns
Strategy: fallback
Validate before calling
# before publishing, check whether the diff adds a scheduled reducer: git diff HEAD~1 -- module/ | grep -E 'spacetimedb::scheduled' # a hit on an added (not pre-existing) schedule means auto-migrate will bail
Try / catch
match publish(&db, &module).await {
Err(e) if e.to_string().contains("Adding schedules is not yet implemented") => {
// dev: delete + republish; prod: schedule a manual migration window
}
other => other,
} Prevention
- Introduce all scheduled reducers in the initial publish of a database, not in later updates.
- Treat schedule additions/removals as breaking changes requiring recreate or manual migration.
- Review schema diffs for #[spacetimedb::scheduled] before every publish to a live database.
When it happens
Trigger: Publishing a module version that declares a new scheduled reducer (#[spacetimedb::scheduled(...)]) or schedule table which did not exist in the previous version, causing AddSchedule to appear in plan.steps.
Common situations: Adding a periodic tick/cron-style reducer to an already-deployed module; introducing recurring background jobs during feature work on a database that must keep its data.
Related errors
- Removing schedules is not yet implemented
- Cannot remove table `{table_name}`: table contains data. Cle
- When providing a name, you must also provide the variants ob
- system tables cannot have schedules, but table {}: {sch:?}
- Precheck failed: added sequence {sequence_name} already has
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/36512f6c8c0fdd61.
Report an issue: GitHub.