gastownhall/beads · critical

loading storage metadata: %w

Error message

loading storage metadata: %w

What it means

In the CGO build of the storage layer, OpenBestAvailable loads the .beads directory's storage metadata via configfile.Load and wraps any failure with 'loading storage metadata: %w'. This means the storage configuration file (e.g. .beads/config.yaml or metadata.yaml) could not be read or parsed, so the backend cannot be selected. The underlying error (permission, missing file, bad YAML) is preserved in the wrap chain.

Source

Thrown at beads_cgo.go:28

	"github.com/steveyegge/beads/internal/storage/backends"
	"github.com/steveyegge/beads/internal/storage/dolt"
	"github.com/steveyegge/beads/internal/storage/embeddeddolt"
)

// OpenBestAvailable opens a beads database using the best available backend
// for the given .beads directory. It reads metadata.json to determine the
// configured mode:
//
//   - Embedded Dolt (default): Opens via the CGo embedded Dolt engine.
//   - Dolt server: Connects to a dolt sql-server via OpenFromConfig.
//
// The returned Storage must be closed when no longer needed.
//
// beadsDir is the path to the .beads directory.
func OpenBestAvailable(ctx context.Context, beadsDir string) (Storage, error) {
	cfg, err := configfile.Load(beadsDir)
	if err != nil {
		return nil, fmt.Errorf("loading storage metadata: %w", err)
	}
	if cfg == nil {
		cfg = configfile.DefaultConfig()
	}
	if !configfile.IsSupportedBackend(cfg.Backend) {
		return nil, configuredBackendUnavailable(cfg.Backend)
	}

	// Dispatch to a registered extension backend before any Dolt path, mirroring
	// the CLI store factories so SDK callers get the backend they registered
	// instead of a silently-opened embedded Dolt store.
	if backend, ok := backends.Lookup(cfg.GetBackend()); ok {
		return backend.Open(ctx, beadsDir)
	}

	if cfg.IsDoltServerMode() {
		store, err := dolt.NewFromConfig(ctx, beadsDir)
		if err != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the underlying wrapped error (errors.Unwrap or %v output) to see whether it is a parse or IO failure
  2. Run bd init in the repo to regenerate valid storage metadata, or restore the metadata file from git
  3. Fix file permissions on the .beads directory (chown/chmod) if the load failed due to access

Example fix

// before
store, err := beads.OpenBestAvailable(ctx, ".beads")
if err != nil { return err }
// after
store, err := beads.OpenBestAvailable(ctx, ".beads")
if err != nil {
    return fmt.Errorf("check .beads storage metadata: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(filepath.Join(beadsDir, "config.yaml")); err != nil {
    return fmt.Errorf(".beads metadata missing; run bd init first: %w", err)
}

Try / catch

store, err := beads.OpenBestAvailable(ctx, dir)
if err != nil {
    return fmt.Errorf("loading storage metadata: %w", err) // inspect wrapped cause
}

Prevention

When it happens

Trigger: Calling OpenBestAvailable(ctx, beadsDir) when the .beads directory exists but its storage metadata file is unreadable, corrupt, or fails configfile.Load validation.

Common situations: Partially-initialized .beads directory (interrupted bd init); a manually edited or truncated config file; permission problems after copying a repo as another user; a stale metadata file from an older beads version.

Related errors


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