clockworklabs/SpacetimeDB · error
view {:?} does not have a backing table
Error message
view {:?} does not have a backing table What it means
While resolving a view for refresh, the system reads the view's catalog row (st_views) and requires table_id — the backing table the view materializes into. A NULL table_id means the catalog view has no backing table, so refresh cannot proceed and resolution fails.
Source
Thrown at crates/core/src/host/module_host.rs:1177
/// type-index references in the `ViewDef`.
pub owning_def: &'a ModuleDef,
}
/// Lookup a module's [`ViewDef`] and check for consistency among
/// its readset, `st_view`, and the [`ModuleDef`].
pub(crate) fn resolve_view_for_refresh<'a>(
tx: &MutTxId,
module_def: &'a ModuleDef,
view_call: &ViewCallInfo,
) -> anyhow::Result<ResolvedViewForRefresh<'a>> {
let st_view = tx
.lookup_st_view(view_call.view_id)
.with_context(|| format!("failed to look up view {}", view_call.view_id))?;
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", view_id))?;
let (global_fn_ptr, view_def, owning_def) = module_def
.view_by_name_with_global_fn_ptr(&st_view.view_name.clone().into())
.ok_or_else(|| {
anyhow::anyhow!(
"view `{}` for view id `{}` not found in current module",
st_view.view_name,
view_id
)
})?;
let is_anonymous = view_def.is_anonymous;
if st_view.is_anonymous != is_anonymous {
return Err(anyhow::anyhow!(
"found is_anonymous={} in st_view, but {} in module when updating view `{}`",
st_view.is_anonymous,
is_anonymous,View on GitHub (pinned to 524b4487d9)
Solutions
- Re-publish the module so the view catalog is rewritten: `spacetime publish <db>`.
- If reproducible and the data is disposable, delete and recreate the database (export first if needed).
- Capture server logs and report to SpacetimeDB with the module code that declares the view.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await refreshViews(db);
} catch (e) {
if (String(e).includes('does not have a backing table')) {
await spacetimePublish(dbName, modulePath); // rewrite view catalog, then retry
return refreshViews(db);
}
throw e;
} Prevention
- Do not kill the server mid-publish; let schema changes complete.
- Re-publish after any failed publish to re-converge the catalog.
- Keep module sources in VCS so catalog state can always be rewritten.
When it happens
Trigger: Refreshing a view whose catalog row was written without a backing table (in-progress or interrupted schema change); refreshing an internal or system view that never has a backing table; catalog/module state drift around view features.
Common situations: Interrupted or partially failed module publishes that altered views; bugs in view catalog maintenance; early adoption of view features before stabilization.
Related errors
- view `{}` for view id `{}` not found in current module
- cannot serialize refs without a typespace
- cannot deserialize refs without a typespace
- Index '${idx.sourceName ?? '<unknown>'}' on table '${tableDe
- Missing type name for ${typeBuilder.constructor.name ?? 'Typ
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/2448e91f856f3333.
Report an issue: GitHub.