{"record":{"id":"1c61fc80b9f4fc86","repo":"tursodatabase/turso","slug":"there-should-be-a-pointer","errorCode":null,"errorMessage":"there should be a pointer","messagePattern":"there should be a pointer","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"core/storage/btree.rs","lineNumber":7048,"sourceCode":"\n                    // Ensure we keep the parent page at the same position as before the replacement.\n                    self.stack\n                        .node_states\n                        .get_mut(btree_depth)\n                        .expect(\"parent page should be on the stack\")\n                        .cell_idx = cell_idx as i32;\n                    let (cell_payload, leaf_cell_idx) = {\n                        let leaf_page = self.stack.top_ref();\n                        let leaf_contents = leaf_page.get_contents();\n                        turso_assert!(leaf_contents.is_leaf());\n                        turso_assert_greater_than!(leaf_contents.cell_count(), 0);\n                        let leaf_cell_idx = leaf_contents.cell_count() - 1;\n                        let last_cell_on_child_page =\n                            leaf_contents.cell_get(leaf_cell_idx, usable_space)?;\n\n                        let mut cell_payload: crate::alloc::Vec<u8> = crate::alloc::vec![];\n                        let child_pointer =\n                            original_child_pointer.expect(\"there should be a pointer\");\n                        // Rewrite the old leaf cell as an interior cell depending on type.\n                        match last_cell_on_child_page {\n                            BTreeCell::TableLeafCell(leaf_cell) => {\n                                // Table interior cells contain the left child pointer and the rowid as varint.\n                                crate::with_btree_allocation_site!(\n                                    CellPayload,\n                                    cell_payload.try_extend(child_pointer.to_be_bytes())\n                                )?;\n                                write_varint_to_vec(leaf_cell.rowid as u64, &mut cell_payload)?;\n                            }\n                            BTreeCell::IndexLeafCell(leaf_cell) => {\n                                // Index interior cells contain:\n                                // 1. The left child pointer\n                                // 2. The payload size as varint\n                                // 3. The payload\n                                // 4. The first overflow page as varint, omitted if no overflow.\n                                crate::with_btree_allocation_site!(\n                                    CellPayload,","sourceCodeStart":7030,"sourceCodeEnd":7066,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/core/storage/btree.rs#L7030-L7066","documentation":"Same InteriorNodeReplacement step: rebuilding the predecessor leaf cell as an interior cell needs original_child_pointer, the left_child_page captured when the interior cell was parsed in DeleteState::FindCell. original_child_pointer.expect(\"there should be a pointer\") fires when that recorded value is None even though the path requires an interior cell.","triggerScenarios":"Deleting through an interior cell where FindCell recorded original_child_pointer = None (cell parsed as a leaf cell on the first pass but as interior later), or state carried across IO re-entry from a non-interior delete.","commonSituations":"Deletes hitting interior cells after IO yields re-enter the state machine, corrupted pages whose cell types changed mid-transaction, engine regressions in DeleteState field plumbing.","solutions":["Report to Turso with the failing DELETE and database - state-plumbing bug or corruption","Run PRAGMA integrity_check on the database","Retry the delete in a fresh transaction; single-statement repros usually succeed on retry","Update to the latest engine version if the delete path was recently touched"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(AssertUnwindSafe(|| {\n    conn.execute(\"DELETE FROM t WHERE id = ?\", [id])\n}));\nif result.is_err() {\n    conn.close().ok(); // engine state suspect; reopen from disk\n}","preventionTips":["Verify database integrity before delete campaigns on critical data","Keep engine version current - delete/interior-cell replacement is actively maintained","Wrap destructive statements in explicit transactions so a retry boundary is well-defined","Retain backups; panics of this class indicate engine bugs or corruption, both worth investigating"],"tags":["btree","delete","interior-cell","panic"],"backgroundTag":"corrupt-btree-cell","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"}