gastownhall/beads · error
dolt gc: %w
Error message
dolt gc: %w
What it means
DoltGC executes `CALL DOLT_GC('--archive-level', '0')` to reclaim disk space. The wrapped "dolt gc: %w" error means the stored procedure itself failed. The most common cause is calling it on a connection with an active explicit transaction — DOLT_GC cannot run inside one — or on a Dolt version/engine that lacks the procedure or the --archive-level flag.
Source
Thrown at internal/storage/versioncontrolops/gc.go:14
package versioncontrolops
import (
"context"
"fmt"
)
// DoltGC runs Dolt garbage collection to reclaim disk space. Archive level 0
// writes classic Snappy table files instead of zstd archives.
// conn must be a non-transactional database connection since
// DOLT_GC cannot run inside an explicit transaction.
func DoltGC(ctx context.Context, conn DBConn) error {
if _, err := conn.ExecContext(ctx, "CALL DOLT_GC('--archive-level', '0')"); err != nil {
return fmt.Errorf("dolt gc: %w", err)
}
return nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Ensure conn is a plain autocommit connection (pinned *sql.Conn or *sql.DB), never a *sql.Tx or a session inside an explicit transaction
- Commit/rollback any open transaction before calling DoltGC
- Check the Dolt server version supports DOLT_GC with --archive-level; drop the flag or upgrade if not
- Inspect the wrapped error for 'cannot run in a transaction' vs 'unknown procedure' to distinguish the causes
Example fix
// before: fails — tx connection err := versioncontrolops.DoltGC(ctx, tx) // after: use a non-transactional connection tx.Rollback() conn, _ := db.Conn(ctx) defer conn.Close() err := versioncontrolops.DoltGC(ctx, conn)
Defensive patterns
Strategy: try-catch
Validate before calling
// DOLT_GC cannot run inside an explicit transaction — verify autocommit first
var inTx int
_ = conn.QueryRowContext(ctx, "SELECT @@autocommit").Scan(&inTx)
if inTx != 1 {
return errors.New("DoltGC requires a non-transactional autocommit connection")
} Type guard
func isTxErr(err error) bool { return strings.Contains(err.Error(), "transaction") }
func isUnknownProc(err error) bool { return strings.Contains(err.Error(), "DOLT_GC") && strings.Contains(err.Error(), "not found") } Try / catch
err := versioncontrolops.DoltGC(ctx, conn)
if err != nil {
if isTxErr(err) {
return fmt.Errorf("call DoltGC outside any transaction: %w", err)
}
return fmt.Errorf("gc failed: %w", err)
} Prevention
- Never pass a *sql.Tx or in-transaction conn to DoltGC
- Run GC after operations complete and transactions are closed
- Confirm Dolt version supports DOLT_GC --archive-level before use
- Schedule GC during idle periods to avoid concurrent-session conflicts
When it happens
Trigger: Calling DoltGC with a *sql.Tx or a connection inside BEGIN/COMMIT; running against an old Dolt server that predates DOLT_GC or the --archive-level option; the server refusing GC while other sessions hold the database.
Common situations: Post-flatten cleanup where the caller reused a transactional connection; mixed bd/Dolt versions where archive-level 0 is unsupported; concurrent bd processes keeping the database busy.
Related errors
- ErrTransaction
- failed to begin transaction: %w
- failed to commit is_blocked repairs: %w
- failed to begin transaction: %w
- failed to commit dependency key repairs: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0f9d35124ff91fc3.
Report an issue: GitHub.