gastownhall/beads · error

checking constraint %s on %s: %w

Error message

checking constraint %s on %s: %w

What it means

Wraps a failure from schemaConstraintExists, which probes INFORMATION_SCHEMA.TABLE_CONSTRAINTS for a named foreign-key or check constraint (used by wispDepMissingAnyFinalConstraint, dropWispDepLegacyShape, ensureWispDepFinalKeysAndConstraints). Unlike schemaHasPrimaryKey it asks about one specific name, which add-if-absent steps need. Thrown only on query failure; a missing constraint is a normal result.

Source

Thrown at internal/storage/schema/migration_repairs.go:731

	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
}

// schemaShowCreateTable returns a table's CREATE statement. It is the only
// place Dolt exposes generated-column shape: INFORMATION_SCHEMA.COLUMNS returns
// EXTRA and GENERATION_EXPRESSION empty for a generated column, and IS_GENERATED
// does not exist there at all.
func schemaShowCreateTable(ctx context.Context, db DBConn, table string) (string, error) {
	var name, ddl string
	// table is a package constant, never caller input; SHOW CREATE TABLE takes
	// no placeholders.
	if err := db.QueryRowContext(ctx, "SHOW CREATE TABLE `"+table+"`").Scan(&name, &ddl); err != nil {
		return "", fmt.Errorf("reading SHOW CREATE TABLE %s: %w", table, err)
	}
	return ddl, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped cause and restore connectivity/server.
  2. Re-run the repair; constraint add-if-absent logic is idempotent.
  3. Verify the DB user can SELECT from INFORMATION_SCHEMA.TABLE_CONSTRAINTS.
  4. Check for ctx deadline issues on very large databases and retry with a longer timeout.
Defensive patterns

Strategy: retry

Validate before calling

var n int
err := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
  WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? AND CONSTRAINT_NAME=?`, table, constraint).Scan(&n)

Type guard

func isSchemaProbeErr(err error) bool {
    return strings.Contains(err.Error(), "checking constraint ")
}

Try / catch

if err := ensureWispDepFinalKeysAndConstraints(ctx, db); err != nil {
    if isRetryableDB(err) { return ensureWispDepFinalKeysAndConstraints(ctx, db) }
    return err
}

Prevention

When it happens

Trigger: The SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS query errors during constraint reconciliation in the wisp_dependencies repair — server unreachable, context cancelled, or driver failure.

Common situations: Connection interruption during the multi-step wisp_dependencies reshape; insufficient privileges to read TABLE_CONSTRAINTS; Dolt restart mid-repair.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/0bb41194a1ab2ba8. Report an issue: GitHub.