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

  1. Re-run the command; confirm the file still exists right before invocation
  2. Ensure no concurrent job deletes the database while shrink runs
  3. If on a network/ephemeral mount, copy the DB to local disk first
  4. 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

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


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/ad94e7e959683454. Report an issue: GitHub.