gastownhall/beads · error

embeddeddolt: switching to database: %w

Error message

embeddeddolt: switching to database: %w

What it means

Wraps the SQL error from 'USE `<database>`' after the database was created in initSchema. The database exists (CREATE succeeded) but switching the connection's default database failed — typically a lost connection, context cancellation, or an engine-level error resolving the just-created database. The rest of schema setup needs the default database selected, so it aborts.

Source

Thrown at internal/storage/embeddeddolt/store.go:334

	conn, err := db.Conn(ctx)
	if err != nil {
		return fmt.Errorf("embeddeddolt: pin connection: %w", err)
	}
	defer conn.Close()

	if s.database != "" {
		if !validIdentifier.MatchString(s.database) {
			msg := fmt.Sprintf("embeddeddolt: invalid database name: %q", s.database)
			if strings.ContainsRune(s.database, '-') {
				msg += "; hyphens are not allowed in embedded mode — replace with underscores in .beads/metadata.json dolt_database field, or run 'bd doctor'"
			}
			return errors.New(msg)
		}
		if _, err := conn.ExecContext(ctx, "CREATE DATABASE IF NOT EXISTS `"+s.database+"`"); err != nil {
			return fmt.Errorf("embeddeddolt: creating database: %w", err)
		}
		if _, err := conn.ExecContext(ctx, "USE `"+s.database+"`"); err != nil {
			return fmt.Errorf("embeddeddolt: switching to database: %w", err)
		}
		if s.branch != "" {
			if _, err := conn.ExecContext(ctx, fmt.Sprintf("SET @@%s_head_ref = %s", s.database, sqlStringLiteral(s.branch))); err != nil {
				return fmt.Errorf("embeddeddolt: setting branch: %w", err)
			}
		}
	}

	// Forward-drift guard: if this database's schema is AHEAD of the binary,
	// fail fast with a clear "upgrade bd" message before MigrateUp no-ops and a
	// later query dies on a dropped/renamed column. Embedded mode is the mode
	// the stale-binary incident (#4135/#4137) was observed in. The read-only
	// embedded open (OpenReadOnly) already guards this; the writable open did
	// not. Runs after the USE switch so the version read resolves against the
	// target database.
	if err := schema.CheckForwardDrift(ctx, conn); err != nil {
		return err
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Retry the command; if it recurs, run 'bd doctor' to check database state.
  2. Inspect the wrapped inner error for the exact engine message.
  3. Raise the context timeout for initialization on large/slow setups.
  4. As a last resort, re-initialize the data directory and pull from the Dolt remote.

Example fix

// before
store, err := newStore(shortCtx, cfg) // embeddeddolt: switching to database: context deadline exceeded

// after
store, err := newStore(context.Background(), cfg)
Defensive patterns

Strategy: retry

Try / catch

if err := store.Init(ctx); err != nil && strings.Contains(err.Error(), "switching to database") {
    select {
    case <-ctx.Done():
        // deadline: retry with longer timeout
    default:
        // transient engine error: retry once
    }
    return store.Init(initCtxLong)
}

Prevention

When it happens

Trigger: newStore -> initSchema with s.database != "" where the USE statement fails: (1) ctx cancelled/timed out between CREATE DATABASE and USE; (2) engine dropped the pinned connection after the CREATE; (3) metadata inconsistency where the engine cannot resolve the database it just created.

Common situations: Slow or flaky environments (containers, network filesystems) where engine operations intermittently fail; very long init exceeding the caller's context deadline; partial state from an earlier crashed init.

Related errors


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