benbjohnson/litestream · error

get size after delete

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.

Solutions

  1. Ensure nothing else deletes or moves the database while shrink runs
  2. Re-run the command on a stable local filesystem
  3. Check the wrapped inner error for the exact syscall/errno to identify the cause
  4. 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

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


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

Appendix: 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)