tursodatabase/turso · error
DB should not be initialized and should not do any IO
Error message
DB should not be initialized and should not do any IO
What it means
Pager::allocate_page1 in its Start step asserts the database is uninitialized and expects the cached header to be available without IO (IOResult::Done from with_header). Receiving an IO suspension instead means a header read was scheduled - contradicting the fresh-database precondition - so it panics to protect the first-page allocation state machine.
Source
Thrown at core/storage/pager.rs:5580
page.unpin();
break;
}
}
}
*state = FreePageState::Start;
Ok(IOResult::Done(()))
}
#[instrument(skip_all, level = Level::DEBUG)]
pub fn allocate_page1(&self) -> IOResultOr<PageRef> {
let state = self.allocate_page1_state.read().clone();
match state {
AllocatePage1State::Start => {
turso_assert!(!self.db_initialized());
tracing::trace!("allocate_page1(Start)");
let IOResult::Done(mut default_header) = self.with_header(|header| *header)? else {
panic!("DB should not be initialized and should not do any IO");
};
turso_assert_eq!(default_header.database_size.get(), 0);
default_header.database_size = 1.into();
// Use cached reserved_space if set (e.g., by sync engine before page allocation),
// otherwise fall back to IOContext's encryption/checksum requirements.
let reserved_space_bytes = self.get_reserved_space().unwrap_or_else(|| {
let io_ctx = self.io_ctx.read();
io_ctx.get_reserved_space_bytes()
});
default_header.reserved_space = reserved_space_bytes;
self.set_reserved_space(reserved_space_bytes);
if let Some(size) = self.get_page_size() {
default_header.page_size = size;
}
View on GitHub (pinned to 492c4a71cd)
Solutions
- If contributing: verify db_initialized() is false and no header read is pending before calling allocate_page1
- Order new caller paths (sync, recovery) so they run before any header IO
- Report with a backtrace if reached without core modifications
Defensive patterns
Strategy: validation
Validate before calling
// precondition before first-page allocation assert!(!pager.db_initialized()); // ensure no header read is in flight when entering allocate_page1
Prevention
- allocate_page1 is bootstrap-only: reserve it for empty databases
- Order sync-engine and recovery setup so no header IO precedes page-1 allocation
When it happens
Trigger: Internal: calling allocate_page1 after the pager already initialized (header read pending or database already open), e.g. recovery or sync-engine code paths that allocate page 1 for an existing database.
Common situations: Contributor changes to bootstrap/recovery ordering; sync-engine setup allocating pages before initialization completes.
Related errors
- invalid position to read current mvcc row
- Invalid btree seek state in seek_btree_and_set_peek: {:?}
- Page size too small, a ptrmap page cannot map any db pages.
- spill_append_frames_to_wal requires a WAL
- buffer not loaded
AI-assisted analysis of tursodatabase/turso@492c4a71cd (2026-08-20).
Data as JSON: /api/errors/139efc2ef99b555d.
Report an issue: GitHub.