tursodatabase/turso · error
has_hole is not supported for the given IO implementation
Error message
has_hole is not supported for the given IO implementation
What it means
has_hole() is an optional method on the IO trait whose default implementation panics. Only IO backends implementing sparse-file semantics can answer it; the sync engine uses it in partial-sync mode and core database code never calls it. Invoking it on a backend that did not override it crashes.
Source
Thrown at core/io/mod.rs:209
if let Err(e) = self.pwrite(pos, buf.clone(), child_c) {
c.abort();
return Err(e);
}
pos += len as u64;
}
Ok(c)
}
fn size(&self) -> Result<u64>;
fn truncate(&self, len: u64, c: Completion) -> Result<Completion>;
/// Optional method implemented by the IO which supports "partial" files (e.g. file with "holes")
/// This method is used in sync engine only for now (in partial sync mode) and never used in the core database code
///
/// The hole is the contiguous file region which is not allocated by the file-system
/// If there is a single byte which is allocated within a given range - method must return false in this case
// todo: need to add custom completion type?
fn has_hole(&self, _pos: usize, _len: usize) -> Result<bool> {
panic!("has_hole is not supported for the given IO implementation")
}
/// Optional method implemented by the IO which supports "partial" files (e.g. file with "holes")
/// This method is used in sync engine only for now (in partial sync mode) and never used in the core database code
// todo: need to add custom completion type?
fn punch_hole(&self, _pos: usize, _len: usize) -> Result<()> {
panic!("punch_hole is not supported for the given IO implementation")
}
fn shared_wal_lock_byte(
&self,
_offset: u64,
_exclusive: bool,
_kind: SharedWalLockKind,
) -> Result<()> {
Err(crate::LimboError::InternalError(
"shared WAL coordination byte locking is not supported for this file".into(),
))
}View on GitHub (pinned to 6c72522679)
Solutions
- Use the file-backed platform IO (which implements hole queries) for partial sync
- Disable partial-sync mode and use full sync
- For custom IO: implement has_hole()/punch_hole() backed by SEEK_HOLE/fiemap or an allocation map
Example fix
// before // partial sync over an IO without hole support -> panics in has_hole engine.enable_partial_sync(memory_io); // after // use the file-backed platform IO that implements sparse-file queries engine.enable_partial_sync(platform_file_io);
Defensive patterns
Strategy: fallback
Validate before calling
// enable partial sync only for IO backends known to implement hole queries
fn io_supports_holes(io: &std::sync::Arc<dyn IO>) -> bool {
// match the concrete file-backed PlatformIO types you ship
matches_downcast_to_platform_file_io(io)
}
if !io_supports_holes(&io) { engine.use_full_sync(); } else { engine.enable_partial_sync(io); } Prevention
- Treat has_hole/punch_hole as capabilities: enable partial sync only on file-backed IO on ext4/xfs/btrfs
- Add a per-backend integration test that exercises partial sync before shipping a custom IO
When it happens
Trigger: Enabling partial sync against an IO implementation that does not implement has_hole/punch_hole: in-memory IO, custom test IO backends, or platform variants without sparse-file support.
Common situations: Pointing the sync engine at a memory database in tests; shipping custom IO backends; filesystems lacking hole reporting (some network filesystems).
Related errors
- punch_hole is not supported for the given IO implementation
- getAllRows: exceeded ${MAX_IO_RETRIES} IO retries
- Unknown Turso sync I/O request.
- failed to build IO runtime
- buffer not loaded
AI-assisted analysis of tursodatabase/turso@6c72522679 (2026-08-20).
Data as JSON: /api/errors/945ee81e3ac944cd.
Report an issue: GitHub.