Zackriya-Solutions/meetily · error

Failed to create meeting: {}

Error message

Failed to create meeting: {}

What it means

The INSERT INTO meetings failed inside the transaction; sqlx maps the SQLite result error into the {} — most often 'no such table: meetings' (migrations never ran on this database), a constraint violation (NOT NULL/UNIQUE), or an I/O error (disk full, read-only file). Because this happens inside the tx, all transcript inserts and the commit are skipped and the transaction rolls back when dropped.

Source

Thrown at frontend/src-tauri/src/audio/import.rs:717

    // Start transaction
    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))?;

    // Insert meeting
    sqlx::query(
        "INSERT INTO meetings (id, title, created_at, updated_at, folder_path)
         VALUES (?, ?, ?, ?, ?)",
    )
    .bind(&meeting_id)
    .bind(title)
    .bind(now)
    .bind(now)
    .bind(&folder_path)
    .execute(&mut *tx)
    .await
    .map_err(|e| anyhow!("Failed to create meeting: {}", e))?;

    // Insert transcripts
    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

  1. Check the {} text — 'no such table' means migrations; 'constraint failed' names the violated column
  2. Run and verify migrations at startup, then compare PRAGMA table_info(meetings) against the expected schema
  3. Test the insert manually with the sqlite3 CLI against the same DB file to reproduce the exact error
  4. Confirm the DB file and directory are writable and the disk has space

Example fix

// before — trust the schema blindly
sqlx::query("INSERT INTO meetings (id, title, created_at, updated_at, folder_path) VALUES (?,?,?,?,?)")
    .execute(&mut *tx).await
    .map_err(|e| anyhow!("Failed to create meeting: {}", e))?;

// after — fail fast with a precise cause and context
let res = sqlx::query(
    "INSERT INTO meetings (id, title, created_at, updated_at, folder_path) VALUES (?,?,?,?,?)")
    .bind(&meeting_id).bind(title).bind(now).bind(now).bind(&folder_path)
    .execute(&mut *tx).await;
if let Err(e) = res {
    error!("meeting insert failed id={} folder={}: {}", meeting_id, folder_path, e);
    return Err(anyhow!("Failed to create meeting: {}", e));
}
Defensive patterns

Strategy: validation

Validate before calling

-- run before import to catch schema drift
SELECT name FROM sqlite_master WHERE type='table' AND name='meetings';
-- then compare: PRAGMA table_info(meetings);

Try / catch

On insert failure, log the sqlx error verbatim (it names the missing table or violated constraint) plus the meeting_id and folder_path, then roll back — do not retry constraint or schema errors, they are deterministic.

Prevention

When it happens

Trigger: First import against a database created without migrations (older DB carried over, migration step skipped); a bound field ending up NULL; disk full or DB file read-only at first write; schema drift where the meetings table lacks expected columns.

Common situations: App updated with new schema but migrations failed silently at startup; user restored an old DB from backup; DB made read-only by backup tools; column renamed by a newer app version.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@0281737d87 (2026-08-16). Data as JSON: /api/errors/2979aba9cf036297. Report an issue: GitHub.