benbjohnson/litestream · error

dry run failed: %w

Error message

dry run failed: %w

What it means

`litestream reset --dry-run` enumerates the local LTX files under the database's LTX directory (db.LTXDir()) so it can print what a real reset would remove. If listing those files fails — unreadable directory, permission problems, filesystem errors — the failure is wrapped as "dry run failed" and the command exits before printing the plan. No files are modified because dry-run only reads.

Source

Thrown at cmd/litestream/reset.go:96

		if err != nil {
			return fmt.Errorf("cannot create database from config: %w", err)
		}
	} else {
		db = litestream.NewDB(dbPath)
	}

	// Check if meta path exists
	metaPath := db.MetaPath()
	if _, err := os.Stat(metaPath); os.IsNotExist(err) {
		fmt.Printf("No local state to reset for %s\n", dbPath)
		fmt.Printf("Meta directory does not exist: %s\n", metaPath)
		return nil
	}

	if *dryRun {
		files, err := localLTXFiles(db.LTXDir())
		if err != nil {
			return fmt.Errorf("dry run failed: %w", err)
		}

		fmt.Printf("Dry run: local Litestream state would be reset for: %s\n", dbPath)
		fmt.Printf("Would remove: %s\n", db.LTXDir())
		if len(files) == 0 {
			fmt.Println("No local LTX files would be removed.")
			return nil
		}

		fmt.Println("Files that would be removed:")
		for _, file := range files {
			fmt.Printf("  %s\n", file)
		}
		fmt.Println("No files were removed.")
		return nil
	}

	// Perform the reset

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Check the wrapped inner error to see whether it is a permission or not-found problem
  2. Verify the db path and that `<dbdir>/.-litestream` (LTX dir) exists and is readable: `ls -la <dbpath>/.litestream`
  3. Re-run with sufficient permissions (sudo or correct user/group ownership)
  4. If the directory is already gone, the reset target state may already be achieved — run without --dry-run or skip the reset

Example fix

// before
sudo -u app litestream reset /var/lib/db/app.db --dry-run
// permission denied on /var/lib/db/app.db/.litestream
// after
sudo litestream reset /var/lib/db/app.db --dry-run
Defensive patterns

Strategy: validation

Validate before calling

ltxDir := filepath.Join(filepath.Dir(dbPath), ".litestream")
fi, err := os.Stat(ltxDir)
if err != nil { return fmt.Errorf("ltx dir missing: %w", err) }
if !fi.IsDir() { return fmt.Errorf("%s is not a directory", ltxDir) }
if err := unix.Access(ltxDir, unix.R_OK); err != nil {
    return fmt.Errorf("ltx dir not readable: %w", err)
}

Prevention

When it happens

Trigger: `litestream reset <dbpath> --dry-run` where localLTXFiles(db.LTXDir()) cannot read the LTX directory: directory deleted or renamed mid-run, wrong permissions, path is not a directory, or an I/O error reading directory entries.

Common situations: Running reset as a non-root user against a root-owned db directory; the database path typo'd so the LTX dir resolves to a file; NFS/network volumes returning I/O errors; state already partially removed by a previous reset.

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/2a2a81cff5e28342. Report an issue: GitHub.