gastownhall/beads · error

resolving dolt credential command: %w

Error message

resolving dolt credential command: %w

What it means

During startup in shared-server mode with the Dolt backend, bd resolves a gateway credential command that mints a Dolt server username (dolt.ApplyGatewayCredential). If that resolution fails, the process aborts with this wrapped error rather than opening a database with unknown credentials.

Source

Thrown at cmd/bd/main.go:271

func resolveDoltServerConnection(ctx context.Context, beadsDir string, fileCfg *configfile.Config, doltCfg *dolt.Config) error {
	doltCfg.ServerHost = fileCfg.GetDoltServerHost()
	// Port 0 is fine here — auto-start will resolve it. Use the shared helper
	// rather than DefaultConfig(...).Port: this hand-built doltCfg is handed
	// straight to dolt.New, and a port arriving there without its source is
	// read as a caller assertion (see ApplyResolvedServerPort).
	dolt.ApplyResolvedServerPort(beadsDir, doltCfg)
	doltCfg.ServerSocket = fileCfg.GetDoltServerSocket()
	// A configured credential command targets an authenticating gateway server:
	// run it for a short-lived token used as the connection username. Fail closed
	// — never fall back to the static/root user when a command was configured but
	// failed. Server mode only: embedded stores never present a username, so the
	// command must not run (or fail) embedded opens even when the env var is set.
	// Dolt-only: the gateway credential command mints a Dolt server
	// username. IsSharedServerMode() forces ServerMode true with no backend
	// guard, so non-Dolt metadata must not try to resolve a server username.
	if doltCfg.ServerMode && fileCfg.GetBackend() == configfile.BackendDolt {
		if _, err := dolt.ApplyGatewayCredential(ctx, fileCfg, doltCfg); err != nil {
			return fmt.Errorf("resolving dolt credential command: %w", err)
		}
	}
	if doltCfg.ServerUser == "" {
		doltCfg.ServerUser = fileCfg.GetDoltServerUser()
	}
	// Use the resolved port for credential lookup — metadata.json port
	// and runtime port can diverge (e.g., tunnel on 3308 vs local on 3307).
	doltCfg.ServerPassword = fileCfg.GetDoltServerPasswordForPort(doltCfg.ServerPort)
	doltCfg.ServerTLS = fileCfg.GetDoltServerTLS()
	return nil
}

var (
	runPostRunAutoCommit = maybeAutoCommit
	runPostRunAutoBackup = maybeAutoBackup
	runPostRunAutoExport = maybeAutoExport
	runPostRunAutoPush   = maybeAutoPush
)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Run the configured credential command manually and verify it prints a valid username
  2. Check config.yaml gateway credential command for typos and PATH issues
  3. Refresh the external credentials the helper depends on (tokens, cloud profiles)
  4. Ensure backend is dolt (BackendDolt) if ServerMode is enabled, since non-Dolt backends must skip this step

Example fix

// before (config.yaml)
dolt:
  gatewayCredentialCommand: dolt-gw-creds   # not on PATH
// after
dolt:
  gatewayCredentialCommand: /usr/local/bin/dolt-gw-creds  # absolute path
Defensive patterns

Strategy: validation

Validate before calling

cmd := getConfiguredCredentialCommand() // from config.yaml
if err := exec.Command("sh", "-c", cmd).Run(); err != nil {
    return fmt.Errorf("gateway credential command %q fails: %v", cmd, err)
}

Prevention

When it happens

Trigger: config.yaml or environment sets a Dolt gateway credential command that fails to execute, is missing from PATH, returns non-zero, or emits unparseable output — encountered while resolving server-mode UOW topology in main.go.

Common situations: Credential helper binary not installed or not in PATH; misquoted shell command in config; helper requires cloud credentials (vault token, AWS profile) that are absent/expired; forcing ServerMode via env var on a non-Dolt backend configuration mistake.

Related errors


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