From fcea2b28d0cc488e63e07dfea2cc72e19702daa2 Mon Sep 17 00:00:00 2001 From: Ellie Huxtable Date: Tue, 3 Mar 2026 23:40:45 +0100 Subject: fix: clear script database before rebuild to prevent unique constraint violation (#3232) The script store build() replays all records from the record store into SQLite but never cleared the database first. Stale rows from previous builds caused unique constraint violations on the name index when scripts were renamed or recreated. ## Checks - [ ] I am happy for maintainers to push small adjustments to this PR, to speed up the review cycle - [ ] I have checked that there are no existing pull requests for the same thing --- crates/atuin-scripts/src/database.rs | 13 +++++++++++++ crates/atuin-scripts/src/store.rs | 7 ++++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'crates/atuin-scripts') diff --git a/crates/atuin-scripts/src/database.rs b/crates/atuin-scripts/src/database.rs index 26fb9328..be113526 100644 --- a/crates/atuin-scripts/src/database.rs +++ b/crates/atuin-scripts/src/database.rs @@ -188,6 +188,19 @@ impl Database { Ok(res) } + pub async fn clear(&self) -> Result<()> { + debug!("clearing all scripts from sqlite"); + + sqlx::query("delete from script_tags") + .execute(&self.pool) + .await?; + sqlx::query("delete from scripts") + .execute(&self.pool) + .await?; + + Ok(()) + } + pub async fn delete(&self, id: &str) -> Result<()> { debug!("deleting script {}", id); diff --git a/crates/atuin-scripts/src/store.rs b/crates/atuin-scripts/src/store.rs index ba7a1ca1..e70f6909 100644 --- a/crates/atuin-scripts/src/store.rs +++ b/crates/atuin-scripts/src/store.rs @@ -91,7 +91,12 @@ impl ScriptStore { } pub async fn build(&self, database: Database) -> Result<()> { - // Get all the scripts from the database - they are already sorted by timestamp + // Clear existing data before replaying all records from the store. + // Without this, stale rows can cause unique constraint violations + // when records are replayed (eg name conflicts from renamed scripts). + database.clear().await?; + + // Get all the scripts from the store - they are already sorted by timestamp let scripts = self.scripts().await?; for script in scripts { -- cgit v1.3.1