charmbracelet/crush · error
failed to commit transaction: %w
Error message
failed to commit transaction: %w
What it means
This error wraps a failure that occurred when committing a SQLite transaction while creating a new history (prompt) file entry. The transaction started, all statements inside it succeeded, but tx.Commit() returned an error, so the whole create is rolled back and no File record is persisted. It signals a database-level problem at commit time rather than a query or argument error.
Source
Thrown at internal/history/file.go:126
})
if txErr != nil {
// Rollback the transaction
tx.Rollback()
// Check if this is a uniqueness constraint violation
if strings.Contains(txErr.Error(), "UNIQUE constraint failed") {
if attempt < maxRetries-1 {
// If we have retries left, increment version and try again
version++
continue
}
}
return File{}, txErr
}
// Commit the transaction
if txErr = tx.Commit(); txErr != nil {
return File{}, fmt.Errorf("failed to commit transaction: %w", txErr)
}
file = s.fromDBItem(dbFile)
s.Publish(pubsub.CreatedEvent, file)
return file, nil
}
return file, err
}
func (s *service) Get(ctx context.Context, id string) (File, error) {
dbFile, err := s.q.GetFile(ctx, id)
if err != nil {
return File{}, err
}
return s.fromDBItem(dbFile), nil
}
View on GitHub (pinned to 7944b8e522)
Solutions
- Check free disk space on the volume holding the SQLite database and free up space if full.
- Ensure no other process holds the database lock; close other instances or check the data-dir lock.
- Verify the database file is not corrupted by running integrity checking (PRAGMA integrity_check) and restore from backup if needed.
- Retry the operation once the underlying transient I/O condition is resolved; inspect the wrapped error (%w) for the concrete SQLite error code.
Example fix
// before
file, err := history.Create(ctx, sessionID, prompt)
if err != nil {
return fmt.Errorf("create history: %w", err) // may hide disk-full
}
// after
file, err := history.Create(ctx, sessionID, prompt)
if err != nil {
if errors.Is(err, sqlite.ErrBusy) || diskFull() {
return fmt.Errorf("create history: storage unavailable: %w", err)
}
return fmt.Errorf("create history: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// before creating history entries
if err := checkDiskSpace(dbDir); err != nil {
return fmt.Errorf("insufficient storage for history db: %w", err)
} Try / catch
file, err := history.Create(ctx, sessionID, prompt)
if err != nil {
var sqliteErr sqlite3.Error
if errors.As(err, &sqliteErr) {
// inspect sqliteErr.Code (Busy, Full, Corrupt) and act
}
return fmt.Errorf("history create failed: %w", err)
} Prevention
- Monitor free disk space on the database volume before writes.
- Ensure only one process accesses the DB at a time (use the data-dir lock).
- Log the fully unwrapped error chain to capture the SQLite error code.
When it happens
Trigger: Calling history.Create or CreateVersion (which delegate to createWithVersion) when the underlying SQLite commit fails: disk full, database file locked by another process/connection, I/O error, or the DB connection was closed mid-transaction.
Common situations: Disk quota exhaustion on the machine holding the SQLite database; another Crush process holding the DB lock (no lock file coordination); the database file being on a full or read-only volume; a corrupted database file.
Related errors
- failed to save todos: %w
- failed to begin transaction: %w
- error creating file history: %w
- error creating file history: %w
- failed to get session: %w
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/a6d477a83448b973.
Report an issue: GitHub.