benbjohnson/litestream · error
get initial size: %w
Error message
get initial size: %w
What it means
shrinkDatabase begins by calling getDatabaseSize(c.DB) to record the initial database size; if that fails the error is wrapped as `get initial size: %w`. getDatabaseSize reads the file sizes on disk (main DB plus WAL/SHM sidecars), so this fails on filesystem-level problems, not SQL problems. Note the file existence was already checked in Run, so failures here usually come from a race where the file disappeared, or from sidecar/stat internals.
Source
Thrown at cmd/litestream-test/shrink.go:62
if _, err := os.Stat(c.DB); err != nil {
return fmt.Errorf("database does not exist: %w", err)
}
slog.Info("Starting database shrink operation",
"db", c.DB,
"delete_percentage", c.DeletePercentage,
"vacuum", c.Vacuum,
"checkpoint", c.Checkpoint,
)
return c.shrinkDatabase(ctx)
}
func (c *ShrinkCommand) shrinkDatabase(ctx context.Context) error {
initialSize, err := getDatabaseSize(c.DB)
if err != nil {
return fmt.Errorf("get initial size: %w", err)
}
slog.Info("Initial database size",
"size_mb", initialSize/1024/1024,
)
db, err := sql.Open("sqlite3", c.DB+"?_journal_mode=WAL")
if err != nil {
return fmt.Errorf("open database: %w", err)
}
defer db.Close()
tables, err := c.getTableList(db)
if err != nil {
return fmt.Errorf("get table list: %w", err)
}
slog.Info("Found tables", "count", len(tables))View on GitHub (pinned to 4ed7a308f6)
Solutions
- Re-run the command; confirm the file still exists right before invocation
- Ensure no concurrent job deletes the database while shrink runs
- If on a network/ephemeral mount, copy the DB to local disk first
- Inspect the wrapped inner error (%w) for the exact syscall failure
Defensive patterns
Strategy: retry
Validate before calling
if _, err := os.Stat(dbPath); err != nil {
return fmt.Errorf("database disappeared before shrink: %w", err)
} Try / catch
if err := runShrink(args); err != nil {
if strings.Contains(err.Error(), "get initial size") {
// filesystem race; check file and retry
time.Sleep(time.Second)
return runShrink(args)
}
return err
} Prevention
- Do not run cleanup jobs concurrently against the same temp database
- Keep the database on stable local storage, not network/ephemeral mounts
- Read the wrapped inner error to identify the exact syscall failure
When it happens
Trigger: The database file was removed or renamed between the os.Stat check in Run and the size query; a wrapped stat/os error inside getDatabaseSize (permissions changed, network mount dropped); running against a path on an unmounted volume.
Common situations: Concurrent cleanup jobs deleting temp test databases; the DB lives on an ephemeral or network filesystem that went away mid-run; sandboxed CI where /tmp is wiped between steps.
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 size after delete: %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/ad94e7e959683454.
Report an issue: GitHub.