benbjohnson/litestream · error
get size after delete: %w
Error message
get size after delete: %w
What it means
After the deletion loop completes, shrinkDatabase re-measures the database size with getDatabaseSize(c.DB) to log the post-delete footprint; failure is wrapped as `get size after delete: %w`. Like error 63 this is a filesystem/stat failure, not a SQL failure — the database connection is still open at this point, so the main file certainly existed moments earlier.
Source
Thrown at cmd/litestream-test/shrink.go:100
totalDeleted := int64(0)
for _, table := range tables {
deleted, err := c.deleteFromTable(db, table)
if err != nil {
slog.Error("Failed to delete from table", "table", table, "error", err)
continue
}
totalDeleted += deleted
slog.Info("Deleted rows from table",
"table", table,
"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,
)
}View on GitHub (pinned to 4ed7a308f6)
Solutions
- Ensure nothing else deletes or moves the database while shrink runs
- Re-run the command on a stable local filesystem
- Check the wrapped inner error for the exact syscall/errno to identify the cause
- Treat the shrink as partially complete: deletions already happened even though this measurement failed
Defensive patterns
Strategy: retry
Validate before calling
// ensure no concurrent deletion of the database file // fuser <dbpath> || true # verify nothing else has it open/removing it
Try / catch
if err := runShrink(args); err != nil {
if strings.Contains(err.Error(), "get size after delete") {
log.Printf("shrink deletions may have completed but sizing failed: %v", err)
return err
}
return err
} Prevention
- Exclude active shrink target files from tmpwatch/cleanup jobs
- Run on local disk rather than flaky network mounts
- Remember deletions persist even if this post-step fails — check row counts before re-running
When it happens
Trigger: The database file or its directory became unreadable mid-run (file deleted by an external process, mount dropped, permissions changed); an OS-level stat error inside getDatabaseSize.
Common situations: External cleanup jobs or tmpwatch removing files under /tmp during long deletions on large databases; running on a flaky network filesystem; container filesystem pressure causing I/O errors.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- get initial size: %w
- get final size: %w
- database does not exist: %w
- cannot access SQLite sidecar path: %w
- remove existing output path: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/438c3c691f031b06.
Report an issue: GitHub.