gastownhall/beads · error

schema: pin connection: %w

Error message

schema: pin connection: %w

What it means

This error wraps a failure to acquire a dedicated single connection (*sql.Conn) from the pool via db.Conn(ctx) during schema initialization/migration setup. Migrations pin one connection so session state (SET variables, temp tables) is stable across all migration statements. It is only about grabbing the connection from the Go pool, not about the SQL executed on it.

Source

Thrown at internal/storage/dolt/store.go:2595

// initSchemaOnDB applies pending schema migrations. schema.MigrateUp tracks
// applied versions in schema_migrations and backfills legacy config-driven
// tables. Returns the number of migrations applied.
func initSchemaOnDB(ctx context.Context, db *sql.DB) (int, error) {
	return initSchemaOnDBWithBootstrapHeal(ctx, db, nil, "")
}

// initSchemaOnDBWithBootstrapHeal threads one-shot, incarnation-bound reset
// authority into the migration lock. A nil capability always fails closed.
func initSchemaOnDBWithBootstrapHeal(
	ctx context.Context,
	db *sql.DB,
	bootstrapHeal *schema.FreshBootstrapHealCapability,
	endpoint string,
) (int, error) {
	conn, err := db.Conn(ctx)
	if err != nil {
		return 0, fmt.Errorf("schema: pin connection: %w", err)
	}
	defer conn.Close()

	var dbName string
	if err := conn.QueryRowContext(ctx, "SELECT DATABASE()").Scan(&dbName); err != nil {
		return 0, fmt.Errorf("schema: read database name: %w", err)
	}

	var opts []schema.MigrateLockOption
	if bootstrapHeal != nil {
		opts = append(opts, schema.WithFreshBootstrapHeal(bootstrapHeal, endpoint))
	}
	applied, err := schema.MigrateUpWithLock(ctx, conn, dbName, opts...)
	if err != nil {
		return applied, fmt.Errorf("schema migration: %w", err)
	}
	return applied, nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped cause (%w) with errors.Is/As: context.DeadlineExceeded means retry or increase timeout; driver.ErrBadConn/network errors mean fix connectivity
  2. Verify the Dolt SQL server is up and the DSN host/port/credentials are correct
  3. Increase context timeout or ensure the pool is not saturated (SetMaxOpenConns, long transactions) before schema init
  4. Retry the operation; pool acquisition is transient under load

Example fix

// before
ctx := context.Background()
conn, err := db.Conn(ctx)
// after
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
conn, err := db.Conn(ctx)
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: ensure server is reachable before schema init
if err := db.PingContext(ctx); err != nil {
    return fmt.Errorf("dolt server unreachable: %w", err)
}

Try / catch

// Go: inspect wrapped cause
conn, err := db.Conn(ctx)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        // retry with longer timeout
    }
    var myErr *mysql.MySQLError
    if errors.As(err, &myErr) { /* server-side rejection */ }
    return err
}

Prevention

When it happens

Trigger: Calling schema initialization (initSchemaOnDBWithRetryAndGate / the pin-connection helper) when the sql.DB pool cannot hand out a connection: context canceled/timed out before a free connection is available, pool exhausted with all connections busy past conn lifetime limits, or the driver failing to dial a new connection.

Common situations: Server not running or wrong port in the DSN, context deadline exceeded because migrations queue behind long-held connections, application shutdown canceling ctx mid-init, network blips between app and Dolt SQL server.

Related errors


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