benbjohnson/litestream · error
checkpoint: %w
Error message
checkpoint: %w
What it means
When -checkpoint is passed, shrinkDatabase runs c.runCheckpoint(db), which executes PRAGMA wal_checkpoint(<mode>). Any error is wrapped as `checkpoint: %w`. Checkpointing merges WAL content back into the main database file; it fails when the WAL cannot be processed, most commonly due to concurrent readers/writers or an invalid checkpoint mode string interpolated into the PRAGMA.
Source
Thrown at cmd/litestream-test/shrink.go:110
"rows_deleted", deleted,
)
}
slog.Info("Deletion complete", "total_rows_deleted", totalDeleted)
sizeAfterDelete, err := getDatabaseSize(c.DB)
if err != nil {
return fmt.Errorf("get size after delete: %w", err)
}
slog.Info("Size after deletion",
"size_mb", sizeAfterDelete/1024/1024,
"change_mb", (initialSize-sizeAfterDelete)/1024/1024,
)
if c.Checkpoint {
if err := c.runCheckpoint(db); err != nil {
return fmt.Errorf("checkpoint: %w", err)
}
sizeAfterCheckpoint, _ := getDatabaseSize(c.DB)
slog.Info("Size after checkpoint",
"size_mb", sizeAfterCheckpoint/1024/1024,
"change_from_delete_mb", (sizeAfterDelete-sizeAfterCheckpoint)/1024/1024,
)
}
if c.Vacuum {
if err := c.runVacuum(db); err != nil {
return fmt.Errorf("vacuum: %w", err)
}
sizeAfterVacuum, _ := getDatabaseSize(c.DB)
slog.Info("Size after VACUUM",
"size_mb", sizeAfterVacuum/1024/1024,
"total_reduction_mb", (initialSize-sizeAfterVacuum)/1024/1024,View on GitHub (pinned to 4ed7a308f6)
Solutions
- Use the default PASSIVE mode, or stop other readers/writers before running a FULL/RESTART/TRUNCATE checkpoint
- Verify -checkpoint-mode is exactly one of PASSIVE, FULL, RESTART, TRUNCATE
- Retry when the database is quiet; check the wrapped inner error for the SQL-level cause
- Run `sqlite3 <db> 'PRAGMA wal_checkpoint(PASSIVE);'` manually to reproduce/diagnose
Example fix
// before litestream-test shrink -db test.db -checkpoint -checkpoint-mode TRUNCATE // busy from live readers // after litestream-test shrink -db test.db -checkpoint # or stop readers first, then use -checkpoint-mode TRUNCATE
Defensive patterns
Strategy: try-catch
Validate before calling
mode := "FULL"
switch mode {
case "PASSIVE", "FULL", "RESTART", "TRUNCATE":
default:
return fmt.Errorf("invalid checkpoint mode %q", mode)
} Try / catch
if err := runShrink(args); err != nil {
if strings.Contains(err.Error(), "checkpoint") {
log.Printf("checkpoint failed (likely busy readers or bad mode): %v", err)
// retry later or fall back to PASSIVE
}
return err
} Prevention
- Use PASSIVE mode when other processes may be reading the database
- Only pass -checkpoint-mode values from the documented set: PASSIVE, FULL, RESTART, TRUNCATE
- Schedule FULL/TRUNCATE checkpoints during quiet periods
When it happens
Trigger: Another connection holds read locks so the checkpoint cannot complete (runCheckpoint only errors on SQL failure here, not busy results); c.CheckpointMode contains a value outside PASSIVE/FULL/RESTART/TRUNCATE causing a PRAGMA syntax/argument error; database corruption or I/O error during the checkpoint write.
Common situations: Running shrink against a live database while the application or litestream is actively reading; passing -checkpoint-mode=TRUNCATE on a busy system; typo'd mode like 'Pasive'.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- set synchronous: %w
- checkpoint failed: %w
- enable wal failed, mode=%q
- set page size: %w
- set journal mode: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/9917953ab49f74e3.
Report an issue: GitHub.