clockworklabs/SpacetimeDB · error
`close` was called on this `NoDurability` instance
Error message
`close` was called on this `NoDurability` instance
What it means
NoDurability is the Durability implementation used when no commitlog is configured (e.g. dev/standalone mode). close() sets an AtomicBool (Relaxed ordering) and append_tx checks it, panicking on append-after-close because the transaction would otherwise be silently dropped; it fails loudly instead. Hitting it means a commit raced shutdown: append_tx ran after close() had been called on the same instance.
Source
Thrown at crates/durability/src/imp/mod.rs:46
}
impl<T> Default for NoDurability<T> {
fn default() -> Self {
let (durable_offset, _) = watch::channel(None);
Self {
durable_offset,
closed: AtomicBool::new(false),
_txdata: PhantomData,
}
}
}
impl<T: Send + Sync> Durability for NoDurability<T> {
type TxData = T;
fn append_tx(&self, _: PreparedTx<Self::TxData>) {
if self.closed.load(Ordering::Relaxed) {
panic!("`close` was called on this `NoDurability` instance");
}
}
fn durable_tx_offset(&self) -> DurableOffset {
self.durable_offset.subscribe().into()
}
fn close(&self) -> Close {
self.closed.store(true, Ordering::Relaxed);
future::ready(*self.durable_offset.borrow()).boxed()
}
}
}
View on GitHub (pinned to 6dee26c6ef)
Solutions
- Quiesce committers first: stop accepting commits and await all in-flight commit tasks before calling close().
- In tests, join outstanding write futures (task tracker) before teardown.
- Upgrade spacetimedb: shutdown-ordering races here are treated as bugs and get patched.
Example fix
// before: close while commits may still land durability.close().await; // after: quiesce writers first, then close commit_workers.shutdown().await; // joins all append_tx futures durability.close().await;
Defensive patterns
Strategy: validation
Validate before calling
// shutdown ordering: quiesce committers before closing durability commit_pool.shutdown().await; // joins outstanding append_tx futures, no new commits after durability.close().await;
Prevention
- Single owner for shutdown: stop accepting commits, drain, then close.
- In tests, use task tracking to await all commit tasks before teardown.
- Treat any 'append after close' failure as a shutdown-ordering bug to fix, not noise.
When it happens
Trigger: Durability::close() on NoDurability followed by another Durability::append_tx, e.g. a commit worker still draining while shutdown starts, or a test closing the datastore then committing.
Common situations: Standalone/test runs without a commitlog; test harness teardown ordering that closes durability before joining commit futures; shutdown-ordering regressions.
Related errors
- failed to open directory {} for fsync: {}
- failed to fsync directory {}: {}
- failed to open file {} for fsync: {}
- failed to fsync file {}: {}
- cannot serialize refs without a typespace
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/76558b045c7a1cd3.
Report an issue: GitHub.