clockworklabs/SpacetimeDB · error
view {} does not have a backing table in database
Error message
view {} does not have a backing table in database What it means
The view is defined in the module and registered in the database (the st_view row was found), but that row has no table_id — the backing table where materialized rows live was never created for this view. Evaluation cannot proceed because there is nowhere to materialize results, so view initialization aborts.
Source
Thrown at crates/core/src/host/wasm_common/module_host_actor.rs:1539
..
} = view;
// Full namespaced canonical name: matches both the st_view registration
// (create_view / create_view_with_prefix) and `view_by_name_with_global_fn_ptr`.
let view_name = prefix.join(local_name.clone());
let (global_fn_ptr, _, _) = module_def
.view_by_name_with_global_fn_ptr(&view_name)
.ok_or_else(|| anyhow::anyhow!("view {} not found in module_def", view_name))?;
let st_view = tx
.view_from_name(&view_name)?
.ok_or_else(|| anyhow::anyhow!("view {} not found in database", view_name))?;
let view_id = st_view.view_id;
let table_id = st_view
.table_id
.ok_or_else(|| anyhow::anyhow!("view {} does not have a backing table in database", view_name))?;
let subs = tx.materialized_view_instances_for_view(view_id);
let view_typespace = Arc::new(owning_def.typespace().clone());
if *is_anonymous {
if subs.is_empty() {
continue;
}
view_calls.push(CallViewParams {
view_name: view_name.clone(),
view_id,
table_id,
fn_ptr: global_fn_ptr,
caller: owner_identity,
sender: None,
args: ArgsTuple::nullary(),
row_type: *product_type_ref,
timestamp: Timestamp::now(),
view_typespace: view_typespace.clone(),View on GitHub (pinned to 524b4487d9)
Solutions
- Republish the module so the update path (re)creates the backing table for the view.
- If the registration is stale, drop the broken view registration and republish to re-register cleanly.
- Recreate the database if the state is disposable.
- Check host logs from the original publish for why table creation was skipped or failed.
Defensive patterns
Strategy: validation
Validate before calling
// verify each registered view has a backing table before relying on materialized state
for name in module_def.view_names() {
let v = tx.view_from_name(name)?.context("view missing")?;
anyhow::ensure!(v.table_id.is_some(), "view {name} has no backing table");
} Prevention
- Republish to recreate view registrations after host version upgrades.
- Watch publish logs for view/table creation failures.
- Recreate the database if the view catalog is half-registered and the data is disposable.
When it happens
Trigger: A view registration persisted without creating its backing table: an interrupted or older publish that registered the view but not the table, host versions that did not create backing tables, or catalog corruption after failed updates.
Common situations: Upgrades across host versions that changed how backing tables are created; crashed publishes leaving half-registered views; manual edits to the view catalog.
Related errors
- view {} not found in database
- view {} not found in module_def
- view {:?} does not have a backing table
- view `{}` for view id `{}` not found in current module
- found is_anonymous={} in st_view, but {} in module when upda
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/5932a1039d259ed6.
Report an issue: GitHub.