atuinsh/atuin · error

failed to parse uuid for local store status

Error message

failed to parse uuid for local store status

What it means

A panic in SqliteStore's local store-status routine (sqlite_store.rs:309). It runs `select host, tag, max(idx) from store group by host, tag` to build the sync status, then expects each host string to parse as a UUID. A host value that is not a UUID means the store table contains corrupt or foreign data, and the process aborts — the sibling of the id-column panic in query_row, but on the host column and in the status path (so it typically kills `atuin store status` or sync bookkeeping).

Source

Thrown at crates/atuin-client/src/record/sqlite_store.rs:309

        }
    }

    pub async fn status(&self) -> Result<RecordStatus> {
        let mut status = RecordStatus::new();

        let res: Result<Vec<(String, String, i64)>, sqlx::Error> =
            sqlx::query_as("select host, tag, max(idx) from store group by host, tag")
                .fetch_all(&self.pool)
                .await;

        let res = match res {
            Err(e) => return Err(eyre!("failed to fetch local store status: {}", e)),
            Ok(v) => v,
        };

        for i in res {
            let host = HostId(
                Uuid::from_str(i.0.as_str()).expect("failed to parse uuid for local store status"),
            );

            status.set_raw(host, RecordTag::from(i.1), i.2 as u64);
        }

        Ok(status)
    }

    pub async fn all_tagged(
        &self,
        tag: &RecordTag,
    ) -> Result<Vec<Record<paseto_v4::EncryptedData>>> {
        let res = sqlx::query("select * from store where tag = ?1 order by timestamp asc")
            .bind(tag.as_str())
            .map(Self::query_row)
            .fetch_all(&self.pool)
            .await?;

View on GitHub (pinned to 202f6ad98e)

Solutions

  1. Restore the records database from backup
  2. Identify and delete corrupt rows: select host from store group by host, validate each against UUID shape, then delete rows with invalid hosts (backup the file first)
  3. As a last resort delete the records DB and re-register to rebuild the store (sync will repopulate from other hosts)
  4. Stop the atuin daemon before any manual SQLite surgery

Example fix

-- after (locate + remove corrupt host rows; back up first)
-- sqlite3 ~/.local/share/atuin/records.sqlite3
.backup /tmp/records.bak
DELETE FROM store WHERE host NOT GLOB '????????-????-????-????-????????????';
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check host values before running store status
// sqlite3 ~/.local/share/atuin/records.sqlite3
// SELECT host FROM store GROUP BY host WHERE host NOT GLOB '????????-????-????-????-????????????'; -- fix: use HAVING-style check per row instead:
-- SELECT DISTINCT host FROM store;
-- then validate each against UUID shape and delete bad rows (after .backup)

Try / catch

// expect() panic: not catchable as an error. Validate the host column first and
// keep backups; treat any occurrence as corruption requiring row cleanup or a
// rebuild (delete DB + re-register, then re-sync).

Prevention

When it happens

Trigger: Running local store status / operations that build the store status when at least one row in the store table has a host column that is not a UUID string — same corruption vectors as error 17.

Common situations: Hand-edited or partially restored record stores; another process writing malformed rows; disk or copy corruption; mixing databases from incompatible tools.

Understand the failure class

Related errors


AI-assisted analysis of atuinsh/atuin@202f6ad98e (2026-08-16). Data as JSON: /api/errors/6087eb6e50d7e253. Report an issue: GitHub.