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

  1. Republish the module so the update path (re)creates the backing table for the view.
  2. If the registration is stale, drop the broken view registration and republish to re-register cleanly.
  3. Recreate the database if the state is disposable.
  4. 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

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


AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16). Data as JSON: /api/errors/5932a1039d259ed6. Report an issue: GitHub.