atuinsh/atuin · error
invalid host UUID format in sqlite DB
Error message
invalid host UUID format in sqlite DB
What it means
Panic while converting the `host` column of the record store's `store` table into a Uuid. HostId is the UUID identifying the machine that wrote each record; like the id column it is always a UUID when written by atuin, so a parse failure means the row is corrupt or foreign. The adjacent comment ('pretty fucked so just panic') marks this as intentional fail-fast on store corruption.
Source
Thrown at crates/atuin-client/src/record/sqlite_store.rs:102
.bind(r.host.id.0.as_hyphenated().to_string())
.bind(r.tag.as_str())
.bind(r.timestamp as i64)
.bind(r.version.as_str())
.bind(r.data.raw.as_str())
.bind(r.data.cek.as_str())
.execute(&mut **tx)
.await?;
Ok(())
}
fn query_row(row: SqliteRow) -> Record<paseto_v4::EncryptedData> {
let idx: i64 = row.get("idx");
let timestamp: i64 = row.get("timestamp");
// tbh at this point things are pretty fucked so just panic
let id = Uuid::from_str(row.get("id")).expect("invalid id UUID format in sqlite DB");
let host = Uuid::from_str(row.get("host")).expect("invalid host UUID format in sqlite DB");
Record {
id: RecordId(id),
idx: idx as u64,
host: Host::new(HostId(host)),
timestamp: timestamp as u64,
tag: RecordTag::from(row.get::<String, _>("tag")),
version: RecordVersion::from(row.get::<String, _>("version")),
data: paseto_v4::EncryptedData {
raw: row.get("data"),
cek: row.get("cek"),
},
}
}
async fn load_all(&self) -> Result<Vec<Record<paseto_v4::EncryptedData>>> {
let res =
sqlx::query("select * from store ").map(Self::query_row).fetch_all(&self.pool).await?;View on GitHub (pinned to 15fe1318f1)
Solutions
- Confirm which rows are bad: `sqlite3 store.db 'select host, count(*) from store group by host;'` — any value that is not a 36-char UUID-shaped string is the culprit
- Restore the store file from backup/snapshot (include the -wal and -shm files), then re-sync from the server
- If unrecoverable, move the store aside and let a fresh `atuin sync` repopulate from the record server
- Going forward, avoid running multiple atuin variants or external sqlite writers against the same data directory
Example fix
// before (crates/atuin-client/src/record/sqlite_store.rs:102)
let host = Uuid::from_str(row.get("host")).expect("invalid host UUID format in sqlite DB");
// after (propagate as a decode error)
let host = Uuid::from_str(row.get("host"))
.map_err(|e| sqlx::Error::ColumnDecode { index: "host".into(), source: e.into() })?; // query_row returns Result Defensive patterns
Strategy: validation
Validate before calling
async fn store_hosts_valid(pool: &sqlx::SqlitePool) -> Result<bool, sqlx::Error> {
let bad: i64 = sqlx::query_scalar(
"select count(*) from store where host not glob
'[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*' or length(host) != 36",
)
.fetch_one(pool)
.await?;
Ok(bad == 0)
} Type guard
fn is_valid_uuid(s: &str) -> bool {
uuid::Uuid::parse_str(s).is_ok()
} Try / catch
let res = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
tokio::task::block_on(store.all_tagged(&tag))
}));
if res.is_err() {
// host UUID corruption: stop, snapshot the db, and rebuild the store via re-sync
tracing::error!("store corrupt (bad host UUID) — snapshot store.db, then re-sync");
} Prevention
- Back up the whole data dir (db + wal + shm) atomically, not just store.db
- Avoid force-killing atuin mid-sync; use its normal shutdown
- Validate host/id columns after restoring from any partial backup
When it happens
Trigger: Any record load — `atuin sync`, `atuin kv`, alias/dotfile/script record reads — encountering a store row whose host value is not a valid UUID. Same corruption vectors as the id column: partial writes, manual edits, wrong/forked binary sharing the data dir, mangled file after disk trouble.
Common situations: Hand-edited or truncated store.db; a crash mid-write leaving a torn WAL frame; sharing ~/.local/share/atuin between a stock atuin and an experimental fork with a different schema; backup restored from a partial copy that dropped trailing bytes.
Related errors
- invalid id UUID format in sqlite DB
- failed to parse uuid for local store status
- issue in stats average query
- issue in stats exits query
- issue in stats day of week query
AI-assisted analysis of atuinsh/atuin@15fe1318f1 (2026-08-19).
Data as JSON: /api/errors/484db5a5998d1cab.
Report an issue: GitHub.