benbjohnson/litestream · error

database does not exist: %w

Error message

database does not exist: %w

What it means

The `litestream-test load` command verifies with os.Stat that the database file given via -db exists before starting load generation. If the stat call fails (file missing, path wrong, or permission issue on a path component), it wraps the underlying error in "database does not exist". This is an upfront precondition check so the tool fails fast instead of mid-run.

Source

Thrown at cmd/litestream-test/load.go:61

	fs := flag.NewFlagSet("litestream-test load", flag.ExitOnError)
	fs.StringVar(&c.DB, "db", "", "Database path (required)")
	fs.IntVar(&c.WriteRate, "write-rate", 100, "Writes per second")
	fs.DurationVar(&c.Duration, "duration", 1*time.Minute, "How long to run")
	fs.StringVar(&c.Pattern, "pattern", "constant", "Write pattern (constant, burst, random, wave)")
	fs.IntVar(&c.PayloadSize, "payload-size", 1024, "Size of each write operation in bytes")
	fs.Float64Var(&c.ReadRatio, "read-ratio", 0.2, "Read/write ratio (0.0-1.0)")
	fs.IntVar(&c.Workers, "workers", 1, "Number of concurrent workers")
	fs.Usage = c.Usage
	if err := fs.Parse(args); err != nil {
		return err
	}

	if c.DB == "" {
		return fmt.Errorf("database path required")
	}

	if _, err := os.Stat(c.DB); err != nil {
		return fmt.Errorf("database does not exist: %w", err)
	}

	slog.Info("Starting load generation",
		"db", c.DB,
		"write_rate", c.WriteRate,
		"duration", c.Duration,
		"pattern", c.Pattern,
		"payload_size", c.PayloadSize,
		"read_ratio", c.ReadRatio,
		"workers", c.Workers,
	)

	return c.generateLoad(ctx)
}

func (c *LoadCommand) generateLoad(ctx context.Context) error {
	db, err := sql.Open("sqlite3", c.DB+"?_journal_mode=WAL")
	if err != nil {

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Create the database first with `litestream-test populate -db <path>` or verify the file exists (ls <path>).
  2. Check the path for typos and confirm you are running from the intended working directory (use an absolute path).
  3. If the underlying error is a permission error rather than ENOENT, fix filesystem permissions on the path or its parent directories.

Example fix

// before
litestream-test load -db ./data/test.db
// error: database does not exist

// after
litestream-test populate -db ./data/test.db   # creates the DB
litestream-test load -db ./data/test.db
Defensive patterns

Strategy: validation

Validate before calling

const path = "/path/to/test.db";
import { existsSync, statSync } from "fs";
if (!existsSync(path)) {
  throw new Error(`database does not exist: ${path}; run 'litestream-test populate -db ${path}' first`);
}
if (!statSync(path).isFile()) {
  throw new Error(`-db must be a file, got: ${path}`);
}

Type guard

function dbFileExists(path) {
  try { return statSync(path).isFile(); } catch { return false; }
}

Try / catch

try {
  await run("litestream-test", ["load", "-db", dbPath]);
} catch (e) {
  if (String(e).includes("database does not exist")) {
    await run("litestream-test", ["populate", "-db", dbPath]);
    await run("litestream-test", ["load", "-db", dbPath]);
  } else throw e;
}

Prevention

When it happens

Trigger: Running `litestream-test load -db <path>` where the path does not exist on disk (typo, file deleted, relative path resolved from the wrong working directory, or a non-SQLite file that was never created by populate).

Common situations: Pointing -db at a database you forgot to create with `litestream-test populate` first; typos in the path; running from a different working directory than expected; expecting `load` to create the database (it does not — only populate does).

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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