benbjohnson/litestream · error

create index: %w

Error message

create index: %w

What it means

populateDatabase wraps a failed CREATE INDEX ... ON <table>(timestamp) in this error. When IndexRatio triggers indexing, an index on the timestamp column is created after the table is created. Failure here means the optional index could not be built on the freshly created table.

Source

Thrown at cmd/litestream-test/populate.go:114

			CREATE TABLE %s (
				id INTEGER PRIMARY KEY AUTOINCREMENT,
				data BLOB,
				text_field TEXT,
				int_field INTEGER,
				float_field REAL,
				timestamp INTEGER
			)
		`, tableName)

		if _, err := db.Exec(createSQL); err != nil {
			return fmt.Errorf("create table %s: %w", tableName, err)
		}

		if c.IndexRatio > 0 {
			if rand.Float64() < c.IndexRatio {
				indexSQL := fmt.Sprintf("CREATE INDEX idx_%s_timestamp ON %s(timestamp)", tableName, tableName)
				if _, err := db.Exec(indexSQL); err != nil {
					return fmt.Errorf("create index: %w", err)
				}
			}
			if rand.Float64() < c.IndexRatio {
				indexSQL := fmt.Sprintf("CREATE INDEX idx_%s_int ON %s(int_field)", tableName, tableName)
				if _, err := db.Exec(indexSQL); err != nil {
					return fmt.Errorf("create index: %w", err)
				}
			}
		}
	}

	totalRows := int(targetBytes / int64(c.RowSize))
	rowsPerTable := totalRows / c.TableCount
	if rowsPerTable == 0 {
		rowsPerTable = 1
	}

	slog.Info("Populating database",

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Drop existing idx_* indexes or start from a fresh database file.
  2. Confirm the table schema includes the timestamp column.
  3. Free disk space if the wrapped error is SQLITE_FULL.
  4. Use CREATE INDEX IF NOT EXISTS in a patched build to make re-runs idempotent.

Example fix

// before
indexSQL := fmt.Sprintf("CREATE INDEX idx_%s_timestamp ON %s(timestamp)", tableName, tableName)
// after
indexSQL := fmt.Sprintf("CREATE INDEX IF NOT EXISTS idx_%s_timestamp ON %s(timestamp)", tableName, tableName)
Defensive patterns

Strategy: validation

Validate before calling

var exists int
if err := db.QueryRow("SELECT COUNT(*) FROM sqlite_master WHERE type='index' AND name=?", fmt.Sprintf("idx_%s_timestamp", tableName)).Scan(&exists); err == nil && exists > 0 {
    // skip index creation
}

Try / catch

if _, err := db.Exec(indexSQL); err != nil {
    if strings.Contains(err.Error(), "already exists") {
        return nil // idempotent skip
    }
    return fmt.Errorf("create index: %w", err)
}

Prevention

When it happens

Trigger: db.Exec(indexSQL) fails: an index named idx_<table>_timestamp already exists from a prior run, the timestamp column is missing (schema drift), or a disk I/O error occurred.

Common situations: Re-running populate on a database that already has the indexes; database created by an older tool version with a different schema; insufficient disk space for large index builds.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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