gastownhall/beads · error
checking index %s on %s: %w
Error message
checking index %s on %s: %w
What it means
Wraps a failure from schemaIndexExists, which probes INFORMATION_SCHEMA.STATISTICS to see whether a named index exists on a table (used by ensureWispIsBlockedIndex, dropWispDepLegacyShape, ensureWispDepFinalKeysAndConstraints). STATISTICS is used because plain secondary indexes are not constraints. Thrown only when the probe query itself fails, not when the index is missing.
Source
Thrown at internal/storage/schema/migration_repairs.go:717
if err := db.QueryRowContext(ctx, `
SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND CONSTRAINT_TYPE = 'PRIMARY KEY'
`, table).Scan(&count); err != nil {
return false, err
}
return count > 0, nil
}
// schemaIndexExists reports whether table carries an index (or unique key) of
// the given name. STATISTICS rather than TABLE_CONSTRAINTS because plain
// secondary indexes are not constraints and never appear in the latter.
func schemaIndexExists(ctx context.Context, db DBConn, table, index string) (bool, error) {
var count int
if err := db.QueryRowContext(ctx, `
SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND INDEX_NAME = ?
`, table, index).Scan(&count); err != nil {
return false, fmt.Errorf("checking index %s on %s: %w", index, table, err)
}
return count > 0, nil
}
// schemaConstraintExists reports whether table carries a named constraint --
// foreign key or check. Unlike schemaHasPrimaryKey it asks about one specific
// name, which is what an add-if-absent step needs.
func schemaConstraintExists(ctx context.Context, db DBConn, table, constraint string) (bool, error) {
var count int
if err := db.QueryRowContext(ctx, `
SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND CONSTRAINT_NAME = ?
`, table, constraint).Scan(&count); err != nil {
return false, fmt.Errorf("checking constraint %s on %s: %w", constraint, table, err)
}
return count > 0, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped driver error and restore DB connectivity.
- Re-run the repair — index checks and their follow-up actions are idempotent add-if-absent operations.
- Confirm the DB user can query INFORMATION_SCHEMA.STATISTICS.
- Increase the context timeout if repairs are timing out on large databases.
Defensive patterns
Strategy: retry
Validate before calling
var n int err := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? AND INDEX_NAME=?`, table, index).Scan(&n)
Type guard
func isTransientDBErr(err error) bool {
var ne net.Error
return errors.As(err, &ne) || errors.Is(err, context.DeadlineExceeded)
} Try / catch
if err := ensureWispIsBlockedIndex(ctx, db); err != nil {
if isTransientDBErr(err) { return ensureWispIsBlockedIndex(ctx, db) } // idempotent
return err
} Prevention
- Confirm SELECT access to INFORMATION_SCHEMA.STATISTICS
- Retry repairs on transient errors — checks are add-if-absent
- Keep context deadlines generous
- Run against a connected, healthy server
When it happens
Trigger: The SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS query errors during a repair step — Dolt server down, context cancelled, driver failure, or restricted permissions on INFORMATION_SCHEMA.
Common situations: Connection drop mid-repair; read-only account; Dolt server restart between repair steps; long migration exceeding ctx timeout.
Related errors
- checking wisp_dependencies.%s: %w
- checking wisp_dependencies.depends_on_id: %w
- checking constraint %s on %s: %w
- failed to migrate credential keys: %w
- failed to scan peer for migration: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/3379a2b8c2a52c22.
Report an issue: GitHub.