clockworklabs/SpacetimeDB · error · UpdateDatabaseResult::ErrorExecutingMigration
Trapped while evaluating views during database update
Error message
Trapped while evaluating views during database update
What it means
During a database update (publish/migration), when the update engine requests subscribed-view evaluation, the host runs the views inside the update transaction. If any view traps — a wasm trap or panic while executing view code — this message is produced, the transaction is rolled back (with metrics reported), and the update fails as ErrorExecutingMigration. The database keeps its pre-update state; no partial migration is committed.
Source
Thrown at crates/core/src/host/wasm_common/module_host_actor.rs:732
tx_offset
};
let durable_offset = stdb.durable_tx_offset();
let res: UpdateDatabaseResult = match res {
crate::db::update::UpdateResult::Success => {
let tx_offset = succeed(self.info.clone(), FunctionBudget::ZERO, Duration::ZERO, tx);
UpdateDatabaseResult::UpdatePerformed {
tx_offset,
durable_offset,
}
}
crate::db::update::UpdateResult::EvaluateSubscribedViews => {
let (out, _, trapped) = self.evaluate_subscribed_views(tx, inst)?;
tx = out.tx;
if trapped || out.outcome != ViewOutcome::Success {
let msg = match trapped {
true => "Trapped while evaluating views during database update".to_string(),
false => format!(
"Views evaluation did not complete successfully during database update: {:?}",
out.outcome
),
};
let (_, tx_metrics, reducer) = stdb.rollback_mut_tx(tx);
stdb.report_mut_tx_metrics(reducer, tx_metrics, None);
UpdateDatabaseResult::ErrorExecutingMigration(anyhow::anyhow!(msg))
} else {
let tx_offset =
succeed(self.info.clone(), out.execution_budget_used, out.total_duration, tx);
UpdateDatabaseResult::UpdatePerformed {
tx_offset,
durable_offset,
}
}
}View on GitHub (pinned to 524b4487d9)
Solutions
- Identify the trapping view from the update error context and host logs, then reproduce it against a copy of the production data.
- Make view code total: replace unwrap/expect and unchecked indexing with handled cases.
- Fix the migration so the data view code sees matches its expectations, or stage the view change in a later publish.
- Retry the publish after the fix — the rollback guarantees no partial state from the failed attempt.
Example fix
// before: view traps on empty state
fn view(ctx: &ViewContext) -> Vec<JobRow> {
let first = ctx.table::<Job>().iter().next().unwrap();
vec![first.into()]
}
// after: tolerate the empty case instead of trapping
fn view(ctx: &ViewContext) -> Vec<JobRow> {
ctx.table::<Job>().iter().take(1).map(Into::into).collect()
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before publishing an update, run all views against a restored snapshot
for view in module.views() {
evaluate_view(view, snapshot_db.clone())?; // must not trap on migrated data
} Try / catch
match update_result {
UpdateDatabaseResult::ErrorExecutingMigration(e) => {
// transaction was rolled back automatically — fix the trapping view, then republish
log::warn!("update rejected: {e:#}");
}
other => { /* ... */ }
} Prevention
- Never unwrap/expect or index unchecked inside view code.
- Test the full publish against a database snapshot before production.
- Keep views tolerant of empty and edge-case data.
When it happens
Trigger: Publishing an update where materialized/subscribed view code traps during the post-migration evaluation pass: view code that unwraps None, indexes out of bounds, or otherwise aborts when run against the migrated data.
Common situations: Views written against the old schema shape running once against new data during migration; views assuming non-empty tables or particular column values; migrations leaving data in a state the view code does not handle.
Related errors
- Views evaluation did not complete successfully during databa
- Manual database migrations are not yet implemented
- Publishing aborted by user
- view {:?} does not have a backing table
- view `{}` for view id `{}` not found in current module
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/105d901d539dbb60.
Report an issue: GitHub.