gastownhall/beads · error
embeddeddolt: invalid database name: %q; hyphens are not all
Error message
embeddeddolt: invalid database name: %q; hyphens are not allowed in embedded mode — replace with underscores in .beads/metadata.json dolt_database field, or run 'bd doctor'
What it means
initSchema (invoked from newStore) validates the configured database name before creating/using it. Embedded Dolt forbids hyphens in database identifiers, so a name like 'my-db' fails store construction with guidance to fix .beads/metadata.json or run 'bd doctor'.
Source
Thrown at internal/storage/embeddeddolt/store.go:328
db, cleanup, err := OpenSQL(ctx, s.dataDir, "", "")
if err != nil {
return fmt.Errorf("embeddeddolt: open db: %w", err)
}
defer func() { _ = cleanup() }()
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-onlyView on GitHub (pinned to 71377f2769)
Solutions
- Change dolt_database in .beads/metadata.json to underscores (my-db → my_db)
- Run `bd doctor` to auto-repair the database name
- If data exists under the old name, migrate it (export/import) into the underscore-named database before deleting the old one
Example fix
// before (.beads/metadata.json)
{"dolt_database": "team-beads"}
// after
{"dolt_database": "team_beads"} Defensive patterns
Strategy: validation
Validate before calling
var validIdentifier = regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*$`)
if !validIdentifier.MatchString(dbName) {
return fmt.Errorf("fix dolt_database in .beads/metadata.json: %q", dbName)
} Type guard
func safeDBName(name string) bool {
return strings.TrimSpace(name) != "" && !strings.ContainsRune(name, '-')
} Try / catch
store, err := embeddeddolt.Open(ctx, dir, db, branch)
if err != nil {
if strings.Contains(err.Error(), "hyphens are not allowed") {
return fmt.Errorf("run 'bd doctor' or use underscores in dolt_database: %w", err)
}
return err
} Prevention
- Sanitize directory-derived names: replace '-' with '_' before storing dolt_database
- Validate metadata.json contents on load with the identifier regex
- Run `bd doctor` when setting up a workspace in a hyphenated directory
When it happens
Trigger: Constructing an EmbeddedDoltStore (via Open and friends) whose database field contains hyphens or otherwise fails validIdentifier — typically a dolt_database value derived from a hyphenated project directory name.
Common situations: Beads initialized inside a directory like 'my-app-web'; manual metadata.json edits; projects migrated from layouts that allowed hyphens.
Related errors
- invalid database name: %q; hyphens are not allowed in embedd
- dolt directory is required
- embeddeddolt: requires CGO (build with CGO_ENABLED=1)
- ErrReadOnly
- errClosed
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/3e64409986ce741e.
Report an issue: GitHub.