clockworklabs/SpacetimeDB · error

ChangeTableAccessorName: `{table_name}` not found in new mod

Error message

ChangeTableAccessorName: `{table_name}` not found in new module def

What it means

SpacetimeDB throws this while applying an AutoMigrateStep::ChangeTableAccessorName step of an auto-migration plan: the planner decided a table's accessor name (the module-side alias, e.g. the Rust table type name) changed, but plan.new.find_table((namespace, local)) returns None, so the new alias cannot be read. The migration plan and the module definitions it was generated from are out of sync: the step's table key no longer resolves in the new module def. The publish/update transaction aborts before any mutation is applied for this step.

Source

Thrown at crates/engine/src/update.rs:373

                let stored_name = namespace.join_raw(&index_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 index_schema = table_schema
                    .indexes
                    .iter()
                    .find(|index| index.index_name == stored_name)
                    .ok_or_else(|| anyhow::anyhow!("Index `{index_name}` not found in table `{table_full_name}`"))?;

                log!(logger, "Dropping index `{index_name}` on table `{table_full_name}`");
                stdb.drop_index(tx, index_schema.index_id)?;
            }
            spacetimedb_schema::auto_migrate::AutoMigrateStep::ChangeTableAccessorName(table_name_key) => {
                let (namespace, local) = table_name_key;
                let table_name = joined(namespace, local);
                let (_, new_table_def): (&ModuleDef, &spacetimedb_schema::def::TableDef) =
                    plan.new.find_table(table_name_key).ok_or_else(|| {
                        anyhow::anyhow!("ChangeTableAccessorName: `{table_name}` not found in new module def")
                    })?;

                let table_id = stdb.table_id_from_name_mut(tx, &table_name)?.unwrap();
                let new_alias = namespace.join(new_table_def.accessor_name.clone());

                log!(
                    logger,
                    "Changing table accessor name for `{table_name}` to `{new_alias}`",
                );
                stdb.alter_table_accessor_name(tx, table_id, new_alias)?;
            }
            spacetimedb_schema::auto_migrate::AutoMigrateStep::ChangeColumnAccessorName(table_name_key, col_name) => {
                let (namespace, local) = table_name_key;
                let table_name = joined(namespace, local);
                let (_, new_table_def): (&ModuleDef, &spacetimedb_schema::def::TableDef) =
                    plan.new.find_table(table_name_key).ok_or_else(|| {
                        anyhow::anyhow!("ChangeColumnAccessorName: `{table_name}` not found in new module def")
                    })?;

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Clean-rebuild the module and republish: cargo clean -p <module-crate> (or delete target/), then spacetime build && spacetime publish <db> - removes stale artifacts that desync the plan from the defs.
  2. Split the change into two publishes: first publish the pure accessor rename (stored table name and module path unchanged), then publish the rename/move of the table.
  3. Pin the stored name with #[spacetimedb::table(name = "...")] so accessor renames never change the (namespace, local) key the planner uses.
  4. Verify the SDK, CLI, and server versions used now match the versions that produced the live database; align them in Cargo.toml and CI.
  5. For disposable/dev databases: spacetime publish --delete-data <db> (alias --clear-database) to recreate the schema from scratch and skip auto-migration.
  6. If it reproduces on a clean build with matching versions, capture the module source and open a SpacetimeDB issue - this is an auto_migrate planner invariant violation.

Example fix

// before: one publish combines accessor rename with rename + move to submodule
mod guild {
    #[spacetimedb::table(name = "members")] // was top-level `players`
    pub struct Member {}                     // type was `Player`
}

// after: two publishes, stored name pinned
// publish 1: accessor rename only, same stored name and location
#[spacetimedb::table(name = "players")]
pub struct Member {}
// publish 2 (separate): rename/move the table
mod guild {
    #[spacetimedb::table(name = "members")]
    pub struct Member {}
}
Defensive patterns

Strategy: validation

Validate before calling

use spacetimedb_schema::auto_migrate::AutoMigrateStep;
// Before applying an auto-migrate plan, verify every step resolves in the new def.
for step in &plan.steps {
    if let AutoMigrateStep::ChangeTableAccessorName(key) = step {
        if plan.new.find_table(key).is_none() {
            anyhow::bail!("plan step references table {:?} missing from new module def", key);
        }
    }
}

Type guard

fn table_resolves_in_new_def(plan: &AutoMigratePlan, key: (&str, &str)) -> bool {
    plan.new.find_table(key).is_some()
}

Try / catch

match update_database(&stdb, tx, &plan, ...).await {
    Err(e) if e.to_string().contains("ChangeTableAccessorName")
        && e.to_string().contains("not found in new module def") => {
        // Plan/def desync: fall back to split publishes or, on dev DBs, --delete-data.
    }
    result => result?,
}

Prevention

When it happens

Trigger: A publish where the table's accessor changed (Rust type renamed) while the table was also renamed, moved to a different submodule (changing its namespace key), or deleted in the same build; or stale build artifacts / a different spacetimedb compiler or SDK version producing a new module def that differs from the one the planner diffed in ponder_migrate.

Common situations: Refactors that rename table structs and simultaneously edit #[table(name = ...)] or reorganize modules into submodules; CI pipelines publishing with a different toolchain than the one that built the running database; switching spacetimedb-standalone or CLI versions between publishes.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20). Data as JSON: /api/errors/37351f8b5e1e9c27. Report an issue: GitHub.