gastownhall/beads · error · storage.ErrUnsupported

storage.ErrUnsupported

storage.ErrUnsupported

Error message

%w: bd serve requires a Dolt SQL server; this workspace uses embedded Dolt

What it means

errServeEmbedded returns a storage.ErrUnsupported (Op: "serve", Backend: "embedded-dolt") wrapped with an explanation: bd serve only works against a Dolt SQL server, not the embedded Dolt topology. The mode is kept in the message, not in ErrUnsupported.Backend, so the error taxonomy's Backend field stays a pure backend vocabulary for errors.As matching.

Source

Thrown at cmd/bd/serve.go:619

// `readonly` is also a config key, and PersistentPreRunE has already folded
// both into readonlyMode by the time any RunE runs.
func errServeReadonly() error {
	return errors.New("bd serve is unavailable under strict readonly (--readonly, or readonly in config): " +
		"every server it binds publishes the issue-claim operation, and refusing to start is the only honest " +
		"answer — a server that advertised a claim it could never land would be worse than no server")
}

// errServeEmbedded is the PERMANENT refusal. The message says what the
// workspace is and what serve needs, and promises nothing further: the reason
// is the embedded backend's commit protocol (see serveDatabaseSource), which no
// amount of provider or role plumbing changes.
//
// The mode belongs in the message, not in ErrUnsupported.Backend: that field is
// documented as a BACKEND name and is the embryo of the pluggable-backend error
// taxonomy, so putting a topology string in it would hand every downstream
// errors.As a mixed backend/mode vocabulary.
func errServeEmbedded() error {
	return fmt.Errorf("%w: bd serve requires a Dolt SQL server; this workspace uses embedded Dolt",
		&storage.ErrUnsupported{Op: "serve", Backend: "embedded-dolt"})
}

// serveRoleSource is the surface serveIssueRoles reaches on the store, spelled
// out rather than taken as a whole storage.DoltStorage.
//
// THE POINT IS THE TEST STUBS. A stub that stands in for a store has to satisfy
// whatever this function asks for, and the only affordable way to satisfy a
// hundred-method interface is to embed it and leave it nil — which answers every
// accessor the stub forgot with a promoted method on a nil interface. That is a
// segfault inside the loop below rather than a compile error, and it has landed
// twice: once on GraphCounter in serve_source_test.go, and once on the same role
// in serve_store_identity_test.go, where no local -run pattern named the test
// and only a full-package CI shard found it.
//
// Named narrowly, a stub can DECLARE this set and assert it, so the next role
// added to the loop below is a build failure in the file that has to grow a
// method — with the method's name in the error.

View on GitHub (pinned to 71377f2769)

Solutions

  1. Provision and connect to a real Dolt SQL server, then configure the workspace backend to it.
  2. Use the Dolt-backed server mode (dolthub/driver via a dolt sql-server) before running bd serve.
  3. Handle this error in tooling with errors.As(*storage.ErrUnsupported) and route embedded-mode users to a different command.
  4. Do not attempt to "fix" by editing ErrUnsupported.Backend — the message carries the mode by design.

Example fix

// handle in caller
var ue *storage.ErrUnsupported
if errors.As(err, &ue) && ue.Op == "serve" {
    fmt.Fprintln(os.Stderr, "bd serve unavailable in embedded mode; start a Dolt SQL server")
}
Defensive patterns

Strategy: type-guard

Validate before calling

// before bd serve, check mode
if isEmbeddedMode() {
    return errors.New("bd serve requires a Dolt SQL server; embedded mode not supported")
}

Type guard

var ue *storage.ErrUnsupported
if errors.As(err, &ue) && ue.Op == "serve" && ue.Backend == "embedded-dolt" {
    // embedded topology: bd serve unavailable
}

Try / catch

if err := runServe(...); err != nil {
    var ue *storage.ErrUnsupported
    if errors.As(err, &ue) {
        // route to server-mode setup instructions
    }
}

Prevention

When it happens

Trigger: Running `bd serve` in a workspace whose metadata.json/config resolves to embedded Dolt mode (isEmbeddedMode() true), e.g. embedded mode enabled per GH#3794 gating.

Common situations: Developer workspace using embedded Dolt locally tries to expose the HTTP API via bd serve; CI environments defaulting to embedded mode; mixed setups after switching backends between server and embedded.

Related errors


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