clockworklabs/SpacetimeDB · error · anyhow::Error
Precheck failed: added sequence {sequence_name} already has
Error message
Precheck failed: added sequence {sequence_name} already has values in range What it means
During auto-migration, when a plan step adds a sequence (auto_inc) to an existing table, a precheck iterates rows whose value in that column falls within the sequence's [min..=max] range. If any existing row already holds a value the sequence would generate, migration aborts to prevent future primary-key/ID collisions.
Source
Thrown at crates/engine/src/update.rs:257
.ok_or_else(|| {
anyhow::anyhow!("Precheck failed: added sequence {sequence_name} has invalid min value")
})?;
let max = match sequence_def.max_value {
Some(max) => ty.saturating_value_from_i128(max),
None => ty.saturating_value_from_i128(i128::MAX),
}
.ok_or_else(|| {
anyhow::anyhow!("Precheck failed: added sequence {sequence_name} has invalid max value")
})?;
let range = min..=max;
if stdb
.iter_by_col_range_mut(tx, table_id, sequence_def.column, range)?
.next()
.is_some()
{
anyhow::bail!("Precheck failed: added sequence {sequence_name} already has values in range",);
}
}
}
}
log::info!("Running database update steps: {}", stdb.database_identity());
let mut res = UpdateResult::Success;
for step in plan.steps {
match step {
spacetimedb_schema::auto_migrate::AutoMigrateStep::RemoveTable(table_name_key) => {
let (namespace, local) = table_name_key;
let table_name = joined(namespace, local);
let table_id = stdb.table_id_from_name_mut(tx, &table_name)?.unwrap();
if stdb.table_row_count_mut(tx, table_id).unwrap_or(0) > 0 {
anyhow::bail!(
"Cannot remove table `{table_name}`: table contains data. \View on GitHub (pinned to 6dee26c6ef)
Solutions
- Check the current maximum (SELECT MAX(col) FROM t) and define the sequence to start strictly above it
- Or delete/backfill the conflicting rows so none fall inside the sequence range, then re-run the migration
- If the ids are disposable, clear the table before adding the sequence
- Prefer an explicit, reviewed migration over auto-migrate when the table already holds production data
Example fix
-- before: rows with id 1..50 exist, sequence starts at 1 -> precheck fails ALTER TABLE my_table ... auto_inc on id; -- after: start beyond the current max, or clear the data first SELECT MAX(id) FROM my_table; -- 50 CREATE SEQUENCE my_seq START 51; -- or: DELETE FROM my_table; then re-run the migration
Defensive patterns
Strategy: validation
Validate before calling
-- before adding a sequence to an existing column spacetime sql my-db 'SELECT MAX(id) FROM my_table'; -- the new sequence must start strictly above this value
Prevention
- Add auto_inc at table creation time, not retroactively on populated tables
- Before any migration that adds a sequence, compute MAX(col) and set the start above it
- Keep explicit-id inserts out of columns destined for sequence management
- Use explicit reviewed migrations (spacetime migrate) for tables with production data
When it happens
Trigger: Adding #[auto_inc]/a sequence to a column of a table that already contains rows with values inside the new sequence's range -- e.g. ids 1..50 exist and the sequence starts at 1; or seeded/imported data written with explicit ids before the sequence is introduced.
Common situations: Retrofitting auto_inc onto a manually populated table; importing seed data then adding the sequence in the same release; a migration that re-adds a sequence after data was written by explicit-id inserts.
Related errors
- Cannot remove table `{table_name}`: table contains data. Cle
- TableId `{return_id}` does not exist
- table {} not found in old_module_def
- table should exist in the database for AddConstraint
- Index '${indexLabel}' on table '${tableLabel}' must define a
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/2e23f0b24865357e.
Report an issue: GitHub.