LOW: applyMigration deferred rollback skipped when Commit() fails #125

Open
opened 2026-02-21 09:52:36 +01:00 by clawbot · 0 comments
Collaborator

Bug

In internal/database/migrations.go, applyMigration has:

defer func() {
    if err != nil {
        _ = transaction.Rollback()
    }
}()

_, err = transaction.ExecContext(ctx, string(content))
// ...
_, err = transaction.ExecContext(ctx, "INSERT INTO schema_migrations ...")
// ...
commitErr := transaction.Commit()
if commitErr != nil {
    return fmt.Errorf("failed to commit migration: %w", commitErr)
}

When Commit() fails, the error is stored in commitErr, not err. The deferred function checks err, which is nil (from the last successful ExecContext). So Rollback() is never called.

Impact

In practice, SQLite automatically rolls back failed commits, so data integrity is maintained. However, this is incorrect Go transaction handling and could cause issues with other database drivers or future changes.

Fix

Assign the commit error back to err:

err = transaction.Commit()
if err != nil {
    return fmt.Errorf("failed to commit migration: %w", err)
}
## Bug In `internal/database/migrations.go`, `applyMigration` has: ```go defer func() { if err != nil { _ = transaction.Rollback() } }() _, err = transaction.ExecContext(ctx, string(content)) // ... _, err = transaction.ExecContext(ctx, "INSERT INTO schema_migrations ...") // ... commitErr := transaction.Commit() if commitErr != nil { return fmt.Errorf("failed to commit migration: %w", commitErr) } ``` When `Commit()` fails, the error is stored in `commitErr`, not `err`. The deferred function checks `err`, which is nil (from the last successful ExecContext). So `Rollback()` is never called. ## Impact In practice, SQLite automatically rolls back failed commits, so data integrity is maintained. However, this is incorrect Go transaction handling and could cause issues with other database drivers or future changes. ## Fix Assign the commit error back to `err`: ```go err = transaction.Commit() if err != nil { return fmt.Errorf("failed to commit migration: %w", err) } ```
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: sneak/upaas#125
No description provided.