tursodatabase/turso · critical

there should be a pointer

Error message

there should be a pointer

What it means

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.

Source

Thrown at core/storage/btree.rs:7048

                    // Ensure we keep the parent page at the same position as before the replacement.
                    self.stack
                        .node_states
                        .get_mut(btree_depth)
                        .expect("parent page should be on the stack")
                        .cell_idx = cell_idx as i32;
                    let (cell_payload, leaf_cell_idx) = {
                        let leaf_page = self.stack.top_ref();
                        let leaf_contents = leaf_page.get_contents();
                        turso_assert!(leaf_contents.is_leaf());
                        turso_assert_greater_than!(leaf_contents.cell_count(), 0);
                        let leaf_cell_idx = leaf_contents.cell_count() - 1;
                        let last_cell_on_child_page =
                            leaf_contents.cell_get(leaf_cell_idx, usable_space)?;

                        let mut cell_payload: crate::alloc::Vec<u8> = crate::alloc::vec![];
                        let child_pointer =
                            original_child_pointer.expect("there should be a pointer");
                        // Rewrite the old leaf cell as an interior cell depending on type.
                        match last_cell_on_child_page {
                            BTreeCell::TableLeafCell(leaf_cell) => {
                                // Table interior cells contain the left child pointer and the rowid as varint.
                                crate::with_btree_allocation_site!(
                                    CellPayload,
                                    cell_payload.try_extend(child_pointer.to_be_bytes())
                                )?;
                                write_varint_to_vec(leaf_cell.rowid as u64, &mut cell_payload)?;
                            }
                            BTreeCell::IndexLeafCell(leaf_cell) => {
                                // Index interior cells contain:
                                // 1. The left child pointer
                                // 2. The payload size as varint
                                // 3. The payload
                                // 4. The first overflow page as varint, omitted if no overflow.
                                crate::with_btree_allocation_site!(
                                    CellPayload,

View on GitHub (pinned to 492c4a71cd)

Solutions

  1. Report to Turso with the failing DELETE and database - state-plumbing bug or corruption
  2. Run PRAGMA integrity_check on the database
  3. Retry the delete in a fresh transaction; single-statement repros usually succeed on retry
  4. Update to the latest engine version if the delete path was recently touched
Defensive patterns

Strategy: try-catch

Try / catch

let result = std::panic::catch_unwind(AssertUnwindSafe(|| {
    conn.execute("DELETE FROM t WHERE id = ?", [id])
}));
if result.is_err() {
    conn.close().ok(); // engine state suspect; reopen from disk
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of tursodatabase/turso@492c4a71cd (2026-08-20). Data as JSON: /api/errors/1c61fc80b9f4fc86. Report an issue: GitHub.