Zackriya-Solutions/meetily · error · anyhow::Error
Failed to delete existing transcripts: {}
Error message
Failed to delete existing transcripts: {} What it means
The DELETE FROM transcripts WHERE meeting_id = ? executed inside the new transaction failed. Because a transaction was already started successfully, the likely causes are schema-level (transcripts table or meeting_id column missing after a skipped migration) or lock/I-O problems on the underlying file, not pool acquisition.
Source
Thrown at frontend/src-tauri/src/audio/retranscription.rs:440
let segments = create_transcript_segments(&all_transcripts);
// Save to database
let app_state = app
.try_state::<AppState>()
.ok_or_else(|| anyhow!("App state not available"))?;
// Wrap delete+insert+update in a transaction to prevent data loss
let pool = app_state.db_manager.pool();
let mut conn = pool.acquire().await.map_err(|e| anyhow!("DB error: {}", e))?;
let mut tx = sqlx::Connection::begin(&mut *conn)
.await
.map_err(|e| anyhow!("Failed to start transaction: {}", e))?;
sqlx::query("DELETE FROM transcripts WHERE meeting_id = ?")
.bind(&meeting_id)
.execute(&mut *tx)
.await
.map_err(|e| anyhow!("Failed to delete existing transcripts: {}", e))?;
for segment in &segments {
sqlx::query(
"INSERT INTO transcripts (id, meeting_id, transcript, timestamp, audio_start_time, audio_end_time, duration)
VALUES (?, ?, ?, ?, ?, ?, ?)"
)
.bind(&segment.id)
.bind(&meeting_id)
.bind(&segment.text)
.bind(&segment.timestamp)
.bind(segment.audio_start_time)
.bind(segment.audio_end_time)
.bind(segment.duration)
.execute(&mut *tx)
.await
.map_err(|e| anyhow!("Failed to insert transcript: {}", e))?;
}
View on GitHub (pinned to 0281737d87)
Solutions
- Read the inner error: 'no such table: transcripts' means the schema is missing - run app migrations or recreate the DB.
- 'database is locked' means another writer interfered - retry when idle.
- Run PRAGMA integrity_check on the database file to rule out corruption.
- Restart the app so the setup/migration path runs again.
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the schema exists before starting retranscription
async fn transcripts_table_exists(pool: &SqlitePool) -> bool {
sqlx::query_scalar::<_, i64>(
"SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='transcripts'"
).fetch_one(pool).await.unwrap_or(0) > 0
} Try / catch
// Distinguish schema errors (fix data) from lock errors (retry)
match delete_result {
Err(e) if e.to_string().contains("no such table") => return Err(anyhow!("schema out of date - run migrations")),
Err(e) if is_busy(&e) => retry_after_idle(),
Err(e) => return Err(anyhow!("delete failed: {e}")),
Ok(_) => {}
} Prevention
- Run schema migrations at app startup, before any retranscription is possible.
- Do not point the app at data directories from incompatible older versions without migrating.
- Check DB integrity when unexplained schema errors appear.
When it happens
Trigger: Database created by an older app version whose migrations never produced the transcripts table; a schema where meeting_id was renamed; DB file moved or unmounted between BEGIN and DELETE.
Common situations: App upgraded but migrations did not run; user pointed the app at an old data directory; partially interrupted first-run initialization left a half-built schema.
Related errors
- Failed to query transcript config: {}
- DB error: {}
- Failed to start transaction: {}
- Failed to create meeting: {}
- Failed to insert transcript: {}
AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16).
Data as JSON: /api/errors/26100eef54e4258f.
Report an issue: GitHub.