gastownhall/beads · critical

configured storage backend %q cannot be opened as Dolt

Error message

configured storage backend %q cannot be opened as Dolt

What it means

The backend in metadata.json is supported and recognized, but it is not Dolt (e.g. a newly supported backend this Dolt-specific open path can't handle). requireDoltBackend rejects the open because this factory only knows how to open Dolt workspaces.

Source

Thrown at internal/storage/dolt/open.go:94

	cfg.ServerPortSource = resolved.PortSource
	cfg.ServerPortSharedServer = resolved.PortSharedServer
}

// requireDoltBackend keeps metadata-driven callers from bypassing the storage
// factory and interpreting another backend's workspace as Dolt. Removed backend
// identifiers deliberately remain recognizable in metadata so this check can fail
// closed instead of opening a new, empty Dolt database.
func requireDoltBackend(fileCfg *configfile.Config) error {
	switch fileCfg.Backend {
	case configfile.BackendPostgres, configfile.BackendMySQL, configfile.BackendSQLite:
		return fmt.Errorf("configured storage backend %q is no longer supported and cannot be opened as Dolt: %s", fileCfg.Backend, configfile.RemovedBackendDetail(fileCfg.Backend))
	}
	if !configfile.IsSupportedBackend(fileCfg.Backend) {
		return fmt.Errorf("configured storage backend %q in metadata.json is not recognized and cannot be opened as Dolt; %s", fileCfg.Backend, configfile.BackendNotOpenedGuarantee)
	}
	backend := fileCfg.GetBackend()
	if backend != configfile.BackendDolt {
		return fmt.Errorf("configured storage backend %q cannot be opened as Dolt", backend)
	}
	return nil
}

// NewFromConfig creates a DoltStore based on the metadata.json configuration.
// beadsDir is the path to the .beads directory.
func NewFromConfig(ctx context.Context, beadsDir string) (*DoltStore, error) {
	return NewFromConfigWithOptions(ctx, beadsDir, nil)
}

// NewFromConfigWithCLIOptions creates a DoltStore using the standalone CLI
// auto-start policy from cmd/bd/main.go. This is for CLI helper paths like
// `bd doctor` that should behave the same way as normal top-level CLI commands
// while still honoring externally managed server mode.
func NewFromConfigWithCLIOptions(ctx context.Context, beadsDir string, cfg *Config) (*DoltStore, error) {
	fileCfg, err := configfile.Load(beadsDir)
	if err != nil {
		return nil, fmt.Errorf("loading config: %w", err)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Open the store with the constructor/factory matching the configured backend instead of the Dolt one
  2. If Dolt is intended, set backend to "dolt" in metadata.json
  3. Use the generic storage factory to dispatch on the configured backend automatically
  4. Verify which backend your .beads directory actually contains before choosing the open path

Example fix

// before: forcing the Dolt constructor
store, err := dolt.NewFromConfigWithOptions(beadsDir, opts)

// after: dispatch on configured backend
store, err := storage.OpenFromConfig(beadsDir, opts)
Defensive patterns

Strategy: fallback

Validate before calling

// Dispatch on backend instead of assuming Dolt
cfg, _ := configfile.Load(beadsDir)
if cfg.GetBackend() != configfile.BackendDolt {
    return openNonDoltStore(beadsDir, cfg)
}

Try / catch

store, err := dolt.NewFromConfigWithOptions(beadsDir, opts)
if err != nil && strings.HasSuffix(err.Error(), "cannot be opened as Dolt") {
    // fall back to the generic backend-dispatching constructor
    store, err = storage.OpenFromConfig(beadsDir, opts)
}

Prevention

When it happens

Trigger: Calling NewFromConfigWithOptions / NewFromConfigWithCLIOptions when fileCfg.GetBackend() returns a valid, supported backend other than configfile.BackendDolt.

Common situations: Using a Dolt-specific store constructor against a workspace configured for another supported backend; switching backends in config without switching the open path; tooling that rewrites metadata.json to a new backend value.

Related errors


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