gastownhall/beads · error
persisting sanitized database name to metadata.json: %w
Error message
persisting sanitized database name to metadata.json: %w
What it means
migrateHyphenatedDB renames a hyphenated Dolt database directory and rewrites metadata.json (GH#3231). If cfg.Save(beadsDir) fails while persisting the sanitized dolt_database name, the error is wrapped so the migration failure is attributed to the metadata write, not the rename.
Source
Thrown at cmd/bd/store_factory.go:220
_, newErr := os.Stat(newDir)
switch {
case newErr == nil:
return fmt.Errorf("cannot auto-migrate database: both %q and %q exist under %s; remove one manually and retry",
oldName, newName, dataDir)
case !os.IsNotExist(newErr):
return fmt.Errorf("checking target directory %q: %w", newDir, newErr)
default:
if err := os.Rename(oldDir, newDir); err != nil {
return fmt.Errorf("renaming database directory: %w", err)
}
fmt.Fprintf(os.Stderr, "bd: migrated database directory %q → %q (GH#3231)\n", oldName, newName)
}
}
if cfg != nil && cfg.DoltDatabase != newName {
cfg.DoltDatabase = newName
if err := cfg.Save(beadsDir); err != nil {
return fmt.Errorf("persisting sanitized database name to metadata.json: %w", err)
}
fmt.Fprintf(os.Stderr, "bd: updated metadata.json dolt_database %q → %q (GH#3231)\n", oldName, newName)
}
return nil
}
// newReadOnlyStoreFromConfig creates a read-only storage backend from the beads
// directory's persisted metadata.json configuration.
//
// For embedded mode, invalid characters (hyphens, dots) are sanitized in-memory
// only — no directory renames or metadata.json writes. This prevents cross-repo
// hydration from mutating foreign projects (GH#3231).
func newReadOnlyStoreFromConfig(ctx context.Context, beadsDir string) (storage.DoltStorage, error) {
return openNonMutatingStoreFromConfig(ctx, beadsDir, false)
}
// newPreviewStoreFromConfig is newReadOnlyStoreFromConfig for a preview
// command (--dry-run, --inspect) reading a repository it was only pointed at:View on GitHub (pinned to 71377f2769)
Solutions
- Check write permission on .beads/metadata.json and the beads dir for the running user.
- Free disk space / check quota if Save failed on write.
- Manually update dolt_database in metadata.json to the sanitized (underscore) name to match the renamed directory.
- Retry the operation after fixing the environment; the rename is idempotent once metadata matches.
Example fix
// after manual repair: # metadata.json "dolt_database": "my_project_db" # was "my-project-db"; directory already renamed
Defensive patterns
Strategy: try-catch
Validate before calling
mdPath := filepath.Join(beadsDir, "metadata.json")
if info, err := os.Stat(mdPath); err != nil || info.Mode().Perm()&0200 == 0 {
// cannot persist sanitized name; fix permissions first
} Try / catch
if err := migrateHyphenatedDB(beadsDir, oldName, newName, cfg); err != nil {
if strings.Contains(err.Error(), "persisting sanitized database name") {
// fix metadata.json writability, align dolt_database manually, retry
}
return err
} Prevention
- Ensure .beads/metadata.json is writable by the bd process user.
- Avoid hyphenated Dolt database names so migration never triggers.
- Monitor disk space/quota on the workspace volume.
- After any hyphenated migration, verify metadata.json dolt_database matches the renamed directory.
When it happens
Trigger: During newDoltStoreFromConfig, when the configured DoltDatabase contains hyphens, the directory rename succeeds, but writing the updated metadata.json fails (read-only beads dir, permission denied, disk full, corrupt config file state).
Common situations: Read-only mount of the .beads directory; running bd under a user without write permission to metadata.json; disk quota exhaustion; concurrent processes holding conflicting writes.
Related errors
- failed to open JSONL: %w
- building hook migration plan: %w
- applying hook migration: %w
- failed to migrate database %s to %s: %w
- reading source content for %s from %s: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/00be0cc60fc564d4.
Report an issue: GitHub.