t8y2/dbx · error
SQLite backup failed: {error}
Error message
SQLite backup failed: {error} What it means
conn.backup(DatabaseName::Main, dest, None) returned an error while performing an online SQLite backup; the worker wraps the rusqlite error in this message. Common underlying causes are I/O problems on the destination, a locked/busy source, or corruption.
Source
Thrown at crates/dbx-sqlite-worker/src/runtime.rs:211
}
Err(error) => WorkerBody::err(error.to_string()),
}
}
fn backup(conn: &Connection, dest: &str) -> WorkerBody {
if dest.trim().is_empty() || dest.contains('\0') {
return WorkerBody::err("Backup destination is invalid");
}
if let Some(parent) = Path::new(dest).parent() {
if !parent.as_os_str().is_empty() {
if let Err(error) = std::fs::create_dir_all(parent) {
return WorkerBody::err(error.to_string());
}
}
}
match conn.backup(DatabaseName::Main, dest, None) {
Ok(()) => WorkerBody::ok(),
Err(error) => WorkerBody::err(format!("SQLite backup failed: {error}")),
}
}
fn restore(conn: &mut Connection, src: &str) -> WorkerBody {
if src.trim().is_empty() || src.contains('\0') {
return WorkerBody::err("Restore source is invalid");
}
match conn.restore(DatabaseName::Main, src, None::<fn(_)>) {
Ok(()) => WorkerBody::ok(),
Err(error) => WorkerBody::err(format!("SQLite restore failed: {error}")),
}
}
fn value_to_json(value: rusqlite::types::ValueRef<'_>, column_decl_type: Option<&str>) -> (serde_json::Value, bool) {
match value {
rusqlite::types::ValueRef::Null => (json!(null), false),
rusqlite::types::ValueRef::Integer(value) => (json!(value), false),
rusqlite::types::ValueRef::Real(value) => (json!(value), false),View on GitHub (pinned to c0390bff16)
Solutions
- Read the wrapped {error} detail to identify the rusqlite/SQLite error code
- Ensure the destination path is writable and the disk has space
- Retry when the source database is not under heavy write load, or use a busy_timeout
- Verify the destination directory exists and permissions allow file creation
Example fix
// before
send(Backup { dest: "/mnt/net/b.db" }); // IOERR
// after
let dest = "/var/backups/local/b.db"; // local writable dir
send(Backup { dest }); // retry on busy with backoff Defensive patterns
Strategy: retry
Validate before calling
fn preflight_backup(conn: &rusqlite::Connection, dest: &str) -> Result<(), String> {
let parent = std::path::Path::new(dest).parent().ok_or("no parent dir")?;
std::fs::create_dir_all(parent).map_err(|e| e.to_string())?;
let f = std::fs::OpenOptions::new().write(true).create(true).open(dest).map_err(|e| e.to_string())?;
drop(f);
Ok(())
} Type guard
fn backup_writable(dest: &str) -> bool {
std::path::Path::new(dest).parent().map_or(false, |p| std::fs::metadata(p).map_or(false, |m| !m.permissions().readonly()))
} Try / catch
match worker.send(WorkerOp::Backup { dest }).await {
Err(body) if body.error().map_or(false, |e| e.starts_with("SQLite backup failed:")) => {
eprintln!("Backup failed: check disk space, permissions, and source locks; retrying");
std::thread::sleep(Duration::from_secs(2));
worker.send(WorkerOp::Backup { dest }).await?
}
other => other?,
} Prevention
- Preflight: ensure dest dir is writable and disk has space
- Avoid backing up during long write transactions; set busy_timeout
- Back up to local disk, then copy to network storage
- Parse the wrapped rusqlite error code to branch (busy vs IO)
When it happens
Trigger: Destination file not writable or on a full filesystem; source database locked by another writer during the backup step; disk I/O error or SQLITE_BUSY/SQLITE_IOERR surfaced through the backup API.
Common situations: Backing up while the app holds long write transactions; backing up to a network mount that drops; permissions changed on the backup directory; disk quota exceeded.
Related errors
- Backup destination is invalid
- Custom H2 JDBC JAR does not exist: " + path
- H2 MVStore file is too small to contain valid headers: " + f
- Failed to read CLOB value
- reader cannot read token payload
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/5a93d452ef4a4ca6.
Report an issue: GitHub.