gastownhall/beads · critical

configured storage backend %q is no longer supported and can

Error message

configured storage backend %q is no longer supported and cannot be opened as Dolt: %s

What it means

Opening a DoltStore was refused because metadata.json records a backend that has been removed from beads (Postgres, MySQL, SQLite). The check fails closed deliberately: beads will not interpret another backend's workspace as Dolt or silently create an empty Dolt database.

Source

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

// So every hand-built dolt.Config that resolves its port this way goes through
// here rather than reaching for .Port. Callers that want to resolve only when
// unset keep their own `if cfg.ServerPort == 0` guard; this function is
// unconditional.
func ApplyResolvedServerPort(beadsDir string, cfg *Config) {
	resolved := doltserver.DefaultConfig(beadsDir)
	cfg.ServerPort = resolved.Port
	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

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use the documented migration path to convert the legacy backend data to Dolt before opening
  2. Restore the correct .beads directory (one with backend: dolt) if the wrong directory was pointed at
  3. Correct metadata.json only if you are certain the directory is actually a Dolt workspace
  4. Consult configfile.RemovedBackendDetail in the error text — it names the specific removal/migration guidance

Example fix

// before: metadata.json from legacy install
{"backend": "sqlite"}

// after: migrate data, then
{"backend": "dolt"}
Defensive patterns

Strategy: validation

Validate before calling

// Check backend before opening with the Dolt factory
cfg, _ := configfile.Load(beadsDir)
if cfg.Backend != "dolt" {
    return fmt.Errorf("refusing Dolt open: backend is %q", cfg.Backend)
}

Try / catch

store, err := dolt.NewFromConfigWithOptions(beadsDir, opts)
if err != nil && strings.Contains(err.Error(), "no longer supported") {
    // run the legacy-backend migration before retrying
    return migrateLegacyBackend(beadsDir)
}

Prevention

When it happens

Trigger: Calling NewFromConfigWithOptions / NewFromConfigWithCLIOptions when fileCfg.Backend is BackendPostgres, BackendMySQL, or BackendSQLite.

Common situations: Upgrading from an older beads version that supported those backends; reusing a .beads directory created by a different tool or fork; hand-editing metadata.json backend field.

Related errors


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