{"record":{"id":"139efc2ef99b555d","repo":"tursodatabase/turso","slug":"db-should-not-be-initialized-and-should-not-do-any","errorCode":null,"errorMessage":"DB should not be initialized and should not do any IO","messagePattern":"DB should not be initialized and should not do any IO","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/storage/pager.rs","lineNumber":5580,"sourceCode":"                    page.unpin();\n                    break;\n                }\n            }\n        }\n        *state = FreePageState::Start;\n        Ok(IOResult::Done(()))\n    }\n\n    #[instrument(skip_all, level = Level::DEBUG)]\n    pub fn allocate_page1(&self) -> IOResultOr<PageRef> {\n        let state = self.allocate_page1_state.read().clone();\n        match state {\n            AllocatePage1State::Start => {\n                turso_assert!(!self.db_initialized());\n                tracing::trace!(\"allocate_page1(Start)\");\n\n                let IOResult::Done(mut default_header) = self.with_header(|header| *header)? else {\n                    panic!(\"DB should not be initialized and should not do any IO\");\n                };\n\n                turso_assert_eq!(default_header.database_size.get(), 0);\n                default_header.database_size = 1.into();\n\n                // Use cached reserved_space if set (e.g., by sync engine before page allocation),\n                // otherwise fall back to IOContext's encryption/checksum requirements.\n                let reserved_space_bytes = self.get_reserved_space().unwrap_or_else(|| {\n                    let io_ctx = self.io_ctx.read();\n                    io_ctx.get_reserved_space_bytes()\n                });\n                default_header.reserved_space = reserved_space_bytes;\n                self.set_reserved_space(reserved_space_bytes);\n\n                if let Some(size) = self.get_page_size() {\n                    default_header.page_size = size;\n                }\n","sourceCodeStart":5562,"sourceCodeEnd":5598,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/core/storage/pager.rs#L5562-L5598","documentation":"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.","triggerScenarios":"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.","commonSituations":"Contributor changes to bootstrap/recovery ordering; sync-engine setup allocating pages before initialization completes.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// precondition before first-page allocation\nassert!(!pager.db_initialized());\n// ensure no header read is in flight when entering allocate_page1","typeGuard":null,"tryCatchPattern":null,"preventionTips":["allocate_page1 is bootstrap-only: reserve it for empty databases","Order sync-engine and recovery setup so no header IO precedes page-1 allocation"],"tags":["pager","storage","page-1","state-machine","internal","panic"],"backgroundTag":"unexpected-io-state","analyzedSha":"492c4a71cd7c2649e7df83da1471b74f4b1c7aa9","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}