{"record":{"id":"b5791d12afd93eb9","repo":"tursodatabase/turso","slug":"page-number-pgno-is-out-of-bounds-the-database","errorCode":null,"errorMessage":"Page number {pgno} is out of bounds. The database only has {} pages.","messagePattern":"Page number (.+?) is out of bounds\\. The database only has (.+?) pages\\.","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"cli/app.rs","lineNumber":2205,"sourceCode":"            writeln!(self)?;\n        }\n        Ok(())\n    }\n\n    fn dump_database_as_text(&mut self, page_no: Option<i64>) -> anyhow::Result<()> {\n        let metadata = self.fetch_db_metadata()?;\n        tracing::debug!(\n            page_size = metadata.page_size,\n            page_count = metadata.page_count,\n            \"Fetched metadata\"\n        );\n\n        if let Some(pgno) = page_no {\n            if pgno <= 0 {\n                anyhow::bail!(\"Page number must be a positive integer.\");\n            }\n            if pgno > metadata.page_count {\n                anyhow::bail!(\n                    \"Page number {pgno} is out of bounds. The database only has {} pages.\",\n                    metadata.page_count\n                );\n            }\n        }\n\n        writeln!(\n            self,\n            \"| size {} pagesize {} filename {}\",\n            metadata.page_count * metadata.page_size,\n            metadata.page_size,\n            &metadata.filename\n        )?;\n\n        let dump_sql = if let Some(pgno) = page_no {\n            format!(\"SELECT pgno, data FROM sqlite_dbpage WHERE pgno = {pgno}\")\n        } else {\n            \"SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno\".to_string()","sourceCodeStart":2187,"sourceCodeEnd":2223,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/cli/app.rs#L2187-L2223","documentation":"Thrown by .dbtotxt when the requested page number exceeds the actual page count of the open database. The count comes from fetch_db_metadata(), which reads the database header, and the check at cli/app.rs:2189 runs before any page is rendered. The message reports both the requested page and the real page count.","triggerScenarios":"`.dbtotxt 42` on a database that has fewer than 42 pages; calling dump_database_as_text(Some(n)) where n > metadata.page_count, e.g. after the file was vacuumed, truncated, or replaced by a smaller one.","commonSituations":"Hard-coded page numbers taken from a dump of a larger database; another connection vacuumed or replaced the file between your assumption and the run; freshly created or empty databases with very few pages.","solutions":["Re-run with a page number between 1 and the page count shown in the error message","Query the true count first: PRAGMA page_count (or read the '| size N pagesize P' header .dbtotxt prints)","If another connection may have vacuumed or replaced the file, reopen the database and retry"],"exampleFix":"-- before\n.dbtotxt 42\n-- ERROR: Page number 42 is out of bounds. The database only has 5 pages.\n\n-- after\n.dbtotxt 5","handlingStrategy":"validation","validationCode":"let page_count: i64 = fetch_single_i64(&mut stmt)?; // PRAGMA page_count\nlet pgno = pgno.clamp(1, page_count);","typeGuard":null,"tryCatchPattern":"match app.dump_database_as_text(Some(pgno)) {\n    Ok(()) => {}\n    Err(e) if e.to_string().contains(\"out of bounds\") => eprintln!(\"page {pgno} beyond page_count; skipping\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Read PRAGMA page_count in the same connection right before dumping","Never hard-code page numbers across database versions or vacuum runs","Reopen the file if another process may have vacuumed or replaced it"],"tags":["cli","dbtotxt","page-number","out-of-bounds","rust"],"backgroundTag":"index-out-of-bounds","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"}