gastownhall/beads · error

newExternalProxiedServerUOWProvider: proxied server root (fr

Error message

newExternalProxiedServerUOWProvider: proxied server root (from env or %s): %w

What it means

When bd builds an external proxied-server unit-of-work provider (cmd/bd/uow_factory.go newExternalProxiedServerUOWProvider), it resolves the server root directory via BEADS_PROXIED_SERVER_ROOT_PATH, the .beads/proxied_server_client_info.json sidecar, or the default Dolt dir, then validates it with validateProxiedServerRootPath. This error wraps any validation failure: the resolved root exists but is not a directory, or os.Stat failed with something other than NotExist (e.g. permission denied on a parent). The message names proxied_server_client_info.json because that sidecar is the usual source of the root path.

Source

Thrown at cmd/bd/uow_factory.go:436

		// concurrent serve. `bd dolt stop` does not reap it in these modes.
		proxyIdle:    proxy.IdleTimeoutNever,
		rootPassword: conn.ServerPassword,
	}, nil
}

// newExternalProxiedServerUOWProvider fronts a Dolt SQL server this process
// neither started nor owns. "Proxied" in the name is the PROXY it builds, not
// the workspace mode: since bd-emv a server-mode workspace lands here too, and
// the paths it resolves (root, log) are the same ones proxied mode uses because
// both modes root their server at the same directory.
func newExternalProxiedServerUOWProvider(ctx context.Context, beadsDir string, topology sqlServerUOWTopology, opts ...uow.ProviderOption) (p uow.UnitOfWorkProvider, err error) {
	defer func() { p, err = activateEventsJournalProvider(ctx, beadsDir, p, err) }()
	rootPath, err := resolveProxiedServerRootPath(beadsDir)
	if err != nil {
		return nil, fmt.Errorf("newExternalProxiedServerUOWProvider: resolve root path: %w", err)
	}
	if err := validateProxiedServerRootPath(rootPath); err != nil {
		return nil, fmt.Errorf("newExternalProxiedServerUOWProvider: proxied server root (from env or %s): %w", configfile.ProxiedServerClientInfoFileName, err)
	}

	logPath, isCustomLog, err := resolveProxiedServerLogPath(beadsDir)
	if err != nil {
		return nil, fmt.Errorf("newExternalProxiedServerUOWProvider: resolve log path: %w", err)
	}
	if isCustomLog {
		if err := validateProxiedServerLogPath(logPath); err != nil {
			return nil, fmt.Errorf("newExternalProxiedServerUOWProvider: proxied server log (from env or %s): %w", configfile.ProxiedServerClientInfoFileName, err)
		}
	}

	if err := os.MkdirAll(rootPath, config.BeadsDirPerm); err != nil {
		return nil, fmt.Errorf("newExternalProxiedServerUOWProvider: mkdir %s: %w", rootPath, err)
	}

	return uow.NewExternalDoltServerUOWProvider(
		ctx,

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check what exists at the resolved path: ls -la on the path from BEADS_PROXIED_SERVER_ROOT_PATH or the sidecar's root_path; if it is a file, remove or rename it so bd can use/create the directory
  2. Fix or unset BEADS_PROXIED_SERVER_ROOT_PATH (unset it to fall back to the sidecar/default), or correct root_path in .beads/proxied_server_client_info.json (bd migrate-dolt-mode writes it)
  3. Verify the parent directories are traversable by the current user (chmod/chown as needed)
  4. Re-run bd migrate-dolt-mode to regenerate a clean proxied_server_client_info.json sidecar

Example fix

// before: env var points at a file
export BEADS_PROXIED_SERVER_ROOT_PATH=/home/me/beads-root.json
// after: point at a (possibly not-yet-existing) directory
export BEADS_PROXIED_SERVER_ROOT_PATH=/var/lib/beads/shared-server/dolt
Defensive patterns

Strategy: validation

Validate before calling

root := os.Getenv("BEADS_PROXIED_SERVER_ROOT_PATH")
if root != "" {
	if fi, err := os.Stat(root); err == nil && !fi.IsDir() {
		return fmt.Errorf("BEADS_PROXIED_SERVER_ROOT_PATH %s is not a directory", root)
	}
}

Type guard

func isDirOrAbsent(path string) bool {
	fi, err := os.Stat(path)
	return err != nil || fi.IsDir()
}

Prevention

When it happens

Trigger: BEADS_PROXIED_SERVER_ROOT_PATH or the sidecar root_path points at a regular file or symlink-to-file instead of a directory; the path exists but the process lacks search permission on a parent directory; a corrupt or hand-edited proxied_server_client_info.json contains a bogus root_path.

Common situations: A user set BEADS_PROXIED_SERVER_ROOT_PATH to a file path (or a stale path now occupied by a file); after switching between modes an old file sits where the root dir should be; restricted service accounts without execute permission on home directories.

Related errors


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