tursodatabase/turso · error · anyhow::Error
record has no column
Error message
record has no column {} on page {root_page} What it means
While walking the record header serial-type varints to reach the target column, the generator checks that the offset stops before the header end. If the header has fewer serial types than `patch.column_index`, the record has no such column and the fixture patch cannot be applied.
Solutions
- Update `patch.column_index` to match the current table schema column ordering.
- Re-generate the fixture so the schema and the patch agree.
- Count stored columns (excluding VIRTUAL generated columns) before choosing column_index.
Example fix
// before
let patch = FirstRowSerialTypePatch { column_index: 5, .. };
// after
let patch = FirstRowSerialTypePatch { column_index: 2, .. }; // matches current schema Defensive patterns
Strategy: validation
Validate before calling
let stored_columns = count_record_serial_types(&page, payload_start)?;
assert!(patch.column_index < stored_columns, "column_index {} >= stored columns {}", patch.column_index, stored_columns); Prevention
- Update column_index whenever the fixture schema changes
- Exclude VIRTUAL generated columns from indexing
- Count header serial types programmatically instead of guessing
When it happens
Trigger: `patch_first_row_serial_type` is called with a `column_index` equal to or greater than the number of columns in the first row's record (e.g. patching column 5 of a 3-column table).
Common situations: The fixture schema was changed (columns added/removed/generated columns) but the patch's `column_index` wasn't updated, or the patch targets a generated-column variant with fewer stored columns.
Related errors
- payload start out of bounds on page
- record header out of bounds on page
- serial types and do not store the same number of bytes
- unexpected serial type
- Too many restrictions specified for collection
AI-assisted analysis of tursodatabase/turso@8d4a589f8d (2026-09-20).
Data as JSON: /api/errors/b0a7cc30e819b301.
Report an issue: GitHub.
Appendix: source
Thrown at testing/sqltest/src/generator/mod.rs:1085
let (header_size, header_size_varint_len) = parse_sqlite_varint(&bytes, payload_start)?;
let header_end = payload_start + header_size as usize;
anyhow::ensure!(
header_end <= bytes.len(),
"record header out of bounds on page {root_page}"
);
let mut serial_offset = payload_start + header_size_varint_len;
for _ in 0..patch.column_index {
let (_, serial_len) = parse_sqlite_varint(&bytes, serial_offset)?;
serial_offset += serial_len;
}
anyhow::ensure!(
serial_offset < header_end,
"record has no column {} on page {root_page}",
patch.column_index
);
anyhow::ensure!(
bytes[serial_offset] == patch.expected_serial_type,
"unexpected serial type {} for column {} of the fixture row, expected {}",
bytes[serial_offset],
patch.column_index,
patch.expected_serial_type
);
bytes[serial_offset] = patch.new_serial_type;
std::fs::write(db_path, bytes)
.with_context(|| format!("failed to write fixture '{}'", db_path.display()))?;
Ok(())
}
async fn generate_non_unique_index_entry_fixture(db_path: &Path) -> Result<()> {
clear_existing_db_and_sidecars(db_path)?;
let db_path_str = db_path.to_string_lossy().to_string();
let db = Builder::new_local(&db_path_str)View on GitHub (pinned to 8d4a589f8d)