clockworklabs/SpacetimeDB · error
RemoveConstraint: `{constraint_name}` not found in old modul
Error message
RemoveConstraint: `{constraint_name}` not found in old module def What it means
Applying RemoveConstraint: the diff planned dropping a constraint that exists in the database but not in the new module, yet plan.old.find_storing_table(namespace, constraint_name) cannot find its owning table in the old module def. The old-def reconstruction does not contain a constraint the database appears to have - the old def and the database's actual history disagree. The publish aborts.
Source
Thrown at crates/engine/src/update.rs:455
.find(|index| index.index_name == stored_name)
.ok_or_else(|| anyhow::anyhow!("Index `{index_name}` not found in table `{table_full_name}`"))?;
let new_source_name = namespace.join_raw(&new_index_def.source_name.clone().into());
log!(
logger,
"Changing index source name for `{}` on table `{}` from `{}` to `{}`",
index_name,
table_full_name,
index_schema.alias.as_deref().unwrap_or(""),
new_source_name,
);
stdb.alter_index_source_name(tx, index_schema.index_id, new_source_name)?;
}
spacetimedb_schema::auto_migrate::AutoMigrateStep::RemoveConstraint(key) => {
let (namespace, constraint_name) = key;
let (_owning_def, table_def) =
plan.old.find_storing_table(namespace, constraint_name).ok_or_else(|| {
anyhow::anyhow!("RemoveConstraint: `{constraint_name}` not found in old module def")
})?;
let table_full_name = joined(namespace, &table_def.name);
let stored_name = namespace.join_raw(&constraint_name.clone().into());
let table_id = stdb.table_id_from_name_mut(tx, &table_full_name)?.unwrap();
let table_schema = stdb.schema_for_table_mut(tx, table_id)?;
let constraint_schema = table_schema
.constraints
.iter()
.find(|constraint| constraint.constraint_name == stored_name)
.unwrap();
log!(
logger,
"Dropping constraint `{constraint_name}` on table `{table_full_name}`"
);
stdb.drop_constraint(tx, constraint_schema.constraint_id)?;
}View on GitHub (pinned to 6dee26c6ef)
Solutions
- Clean-rebuild and republish (removes stale def artifacts).
- Publish constraint changes alone - no renames, moves, or drops in the same build.
- Pin constraint names where supported (e.g. #[unique(name = "...")]) on both module versions.
- Match the toolchain version that published the live database, then migrate stepwise.
- Dev: spacetime publish --delete-data <db>.
- Report persistent cases with the module diff and constraint names.
Example fix
// before: drop #[unique] and rename its column in one publish
pub struct Player {
#[spacetimedb::column(name = "level")] // was `hp`, still unique-keyed before
pub level: u32,
}
// after: two publishes
// 1) remove #[unique] only, keep names
// 2) rename the column separately Defensive patterns
Strategy: fallback
Validate before calling
use spacetimedb_schema::auto_migrate::AutoMigrateStep;
for step in &plan.steps {
if let AutoMigrateStep::RemoveConstraint((namespace, cname)) = step {
if plan.old.find_storing_table(namespace, cname).is_none() {
anyhow::bail!("old def lacks constraint {} - schema drift", cname);
}
}
} Type guard
fn constraint_in_old_def(plan: &AutoMigratePlan, ns: &str, cname: &str) -> bool {
plan.old.find_storing_table(ns, cname).is_some()
} Try / catch
match update_database(&stdb, tx, &plan, ...).await {
Err(e) if e.to_string().contains("RemoveConstraint")
&& e.to_string().contains("old module def") => {
// Fall back: publish the exact prior build first, then remove the constraint stepwise.
}
result => result?,
} Prevention
- Name constraints explicitly (e.g. #[unique(name = "...")]) so auto-names cannot drift across compiler versions.
- Publish constraint removals alone, without renames or moves.
- Record the toolchain version used for each publish.
- Clean-build between toolchain upgrades.
When it happens
Trigger: Constraint auto-names (unique, primary-key-backed) differing between the compiler build that published the database and the current one; renaming/dropping the table or constraint in the same publish as other changes; submodule constraint namespace-prefix drift.
Common situations: Adding or removing #[unique]/#[primary_key] plus renaming fields or tables in one publish; upgrading compiler versions between publishes; moving constrained tables into submodules.
Related errors
- AddConstraint: `{constraint_name}` not found in new module d
- ChangeTableAccessorName: `{table_name}` not found in new mod
- ChangeColumnAccessorName: `{table_name}` not found in new mo
- Column `{col_name}` not found in table `{table_name}`
- ChangeIndexSourceName: `{index_name}` not found in old modul
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/bb65e56d1099ddae.
Report an issue: GitHub.