clockworklabs/SpacetimeDB · error

AddView: view `{view_name}` not found in new module def

Error message

AddView: view `{view_name}` not found in new module def

What it means

Auto-migrate step AddView: plan.new.find_view(view_name_key) returned None — the view the plan intends to create is absent from the new module def. As with AddTable, this signals plan/def desynchronization inside the migration machinery.

Source

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

                stdb.drop_table(tx, table_id)?;
            }
            spacetimedb_schema::auto_migrate::AutoMigrateStep::AddTable(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!("AddTable: table `{table_name}` not found in new module def"))?;
                log!(logger, "Creating table `{table_name}`");
                create_table_from_def_with_prefix(stdb, tx, owning_def, table_def, namespace)?;
            }
            spacetimedb_schema::auto_migrate::AutoMigrateStep::AddView(view_name_key) => {
                let (namespace, local) = view_name_key;
                let view_name = joined(namespace, local);
                let (owning_def, view_def) = plan
                    .new
                    .find_view(view_name_key)
                    .ok_or_else(|| anyhow::anyhow!("AddView: view `{view_name}` not found in new module def"))?;
                create_table_from_view_def_with_prefix(stdb, tx, owning_def, view_def, namespace)?;
            }
            spacetimedb_schema::auto_migrate::AutoMigrateStep::RemoveView(view_name_key) => {
                let (namespace, local) = view_name_key;
                let view_name = joined(namespace, local);
                let view_id = stdb
                    .view_id_from_name_mut(tx, &view_name)?
                    .ok_or_else(|| anyhow::anyhow!("RemoveView: view `{view_name}` not found in database"))?;
                stdb.drop_view(tx, view_id)?;
            }
            spacetimedb_schema::auto_migrate::AutoMigrateStep::UpdateView(_) => {
                // if we already have to disconnect clients, no need to set
                // `EvaluateSubscribedViews` as clients will be disconnected anyway
                if !matches!(res, UpdateResult::RequiresClientDisconnect) {
                    res = UpdateResult::EvaluateSubscribedViews;
                }
            }
            spacetimedb_schema::auto_migrate::AutoMigrateStep::AddIndex(key) => {

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Recompute the plan from the same def that provides plan.new
  2. Verify the (namespace, view name) key resolves in the new def
  3. Report upstream if machine-generated plans still trigger it
Defensive patterns

Strategy: try-catch

Try / catch

match auto_migrate_database(&stdb, &mut tx, auth, &plan, &logger) {
    Err(e) if e.to_string().contains("AddView:") && e.to_string().contains("not found in new module def") => {
        anyhow::bail!("plan/def desync: {e:#}; regenerate the migration plan from the current defs");
    }
    r => r,
}

Prevention

When it happens

Trigger: A migration plan built from a different def than plan.new; view keys with mismatched namespace prefixes; differ bugs emitting AddView for a view not present in the def.

Common situations: Reusing cached plans after editing view definitions; upstream schema-diff changes; manual plan construction in tests.

Related errors


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