{"record":{"id":"32532aadce80850f","repo":"tursodatabase/turso","slug":"page-number-must-be-a-positive-integer","errorCode":null,"errorMessage":"Page number must be a positive integer.","messagePattern":"Page number must be a positive integer\\.","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"cli/app.rs","lineNumber":2202,"sourceCode":"                };\n                write!(self, \"{ch}\")?;\n            }\n            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 {","sourceCodeStart":2184,"sourceCodeEnd":2220,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/cli/app.rs#L2184-L2220","documentation":"Thrown by the tursodb CLI dot-command .dbtotxt when the optional page-number argument is zero or negative. dump_database_as_text takes Option<i64> and validates it before rendering anything, because pages in the SQLite file format are 1-indexed (page 1 is the file header). This is pure argument validation at cli/app.rs:2186; no I/O has happened yet.","triggerScenarios":"Running .dbtotxt with a non-positive page argument, e.g. `.dbtotxt 0` or `.dbtotxt -3`. Programmatically calling dump_database_as_text(Some(pgno)) with a computed pgno that is <= 0.","commonSituations":"Scripts that loop page numbers starting at 0 instead of 1; a computed offset like page_count - n going negative on an empty or single-page database; copy-pasting examples that treat pages as 0-indexed.","solutions":["Pass a 1-based page number: page 1 is the header, valid range is 1..=page_count","Run .dbtotxt with no page argument to dump the whole database instead of one page","If the page is computed dynamically, clamp it before use: pgno.max(1) and check it against PRAGMA page_count"],"exampleFix":"-- before\n.dbtotxt 0\n-- ERROR: Page number must be a positive integer.\n\n-- after\n.dbtotxt 1","handlingStrategy":"validation","validationCode":"let page_count: i64 = fetch_single_i64(&mut conn.query(\"PRAGMA page_count\")?.unwrap())?;\nif let Some(pgno) = page_no {\n    anyhow::ensure!(pgno >= 1, \"page number must be >= 1\");\n}","typeGuard":null,"tryCatchPattern":"match app.dump_database_as_text(Some(pgno)) {\n    Ok(()) => {}\n    Err(e) if e.to_string().contains(\"positive integer\") => eprintln!(\"page must be >= 1, got {pgno}\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Treat page numbers as 1-based; page 1 is the SQLite header page","Validate page numbers against PRAGMA page_count before selecting a page","Clamp computed offsets (max(1)) before passing them to .dbtotxt"],"tags":["cli","dbtotxt","page-number","argument-validation","rust"],"backgroundTag":"argument-validation","analyzedSha":"492c4a71cd7c2649e7df83da1471b74f4b1c7aa9","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}