benbjohnson/litestream · error

ensure test table: %w

Error message

ensure test table: %w

What it means

generateLoad wraps any failure from ensureTestTable (which creates the load_test table and its index if missing) as "ensure test table". This means the schema-setup step for the load generator failed — most often a SQLite error executing the CREATE TABLE/CREATE INDEX statements or a connection failure to the database.

Source

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

		"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 {
		return fmt.Errorf("open database: %w", err)
	}
	defer db.Close()

	db.SetMaxOpenConns(c.Workers + 1)
	db.SetMaxIdleConns(c.Workers)

	if err := c.ensureTestTable(db); err != nil {
		return fmt.Errorf("ensure test table: %w", err)
	}

	ctx, cancel := context.WithTimeout(ctx, c.Duration)
	defer cancel()

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-sigChan
		slog.Info("Received interrupt signal, stopping load generation")
		cancel()
	}()

	stats := &LoadStats{
		startTime:  time.Now(),
		lastReport: time.Now(),
	}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Verify the -db path is a valid SQLite database (`sqlite3 <path> '.tables'` or `file <path>`); recreate it with `litestream-test populate` if it is corrupt or not SQLite.
  2. Check for other processes holding a write lock on the database and close them.
  3. Check disk space and filesystem writability; free space or move the database to a writable location.
  4. Inspect the wrapped inner error for the specific SQLite error code and address it directly.
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the file is a real SQLite database before running load
import { readFileSync } from "fs";
const header = readFileSync(dbPath).subarray(0, 16).toString("utf8");
if (header !== "SQLite format 3\u0000") throw new Error(`${dbPath} is not a SQLite database`);

Type guard

function isSqliteFile(path) {
  try { return readFileSync(path).subarray(0, 16).toString("latin1") === "SQLite format 3\x00"; } catch { return false; }
}

Try / catch

try {
  await run("litestream-test", ["load", "-db", dbPath]);
} catch (e) {
  if (String(e).includes("ensure test table")) {
    console.error("Schema setup failed; recreate the DB with 'litestream-test populate -db " + dbPath + "'");
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `litestream-test load` where the CREATE TABLE IF NOT EXISTS load_test or CREATE INDEX statement fails: the existing file is not a valid SQLite database, the file is corrupted, the disk is full, or the connection dropped.

Common situations: Pointing -db at a non-SQLite file (random bytes, another DB engine's file); a corrupted database from a previous crashed run; read-only filesystem or insufficient disk space; database locked by another process holding an exclusive lock.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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