gastownhall/beads · error

newExternalProxiedServerUOWProvider: proxied server log (fro

Error message

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

What it means

After resolving a custom log path for the external proxied server, newExternalProxiedServerUOWProvider validates it with validateProxiedServerLogPath and wraps failures with this error. Validation requires the log's parent directory to exist and be a directory, and the log itself, if present, to be a regular file. The message names proxied_server_client_info.json because a custom log path typically comes from that sidecar's log_path (or BEADS_PROXIED_SERVER_LOG).

Source

Thrown at cmd/bd/uow_factory.go:445

// 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,
		rootPath,
		topology.database,
		logPath,
		*topology.external,
		topology.external.ResolvedUser(),
		topology.rootPassword,
		topology.proxyPort,
		topology.proxyIdle,
		topology.teamServer,

View on GitHub (pinned to 71377f2769)

Solutions

  1. Create the log's parent directory: mkdir -p $(dirname "$BEADS_PROXIED_SERVER_LOG")
  2. Check that the log path is not a directory or special file (ls -la); remove/rename it if so
  3. Unset BEADS_PROXIED_SERVER_LOG or clear log_path in .beads/proxied_server_client_info.json to fall back to <root>/server.log
  4. Verify permissions allow stat/creation of the parent directory

Example fix

// before: parent missing
export BEADS_PROXIED_SERVER_LOG=/var/log/bd/server.log  # /var/log/bd does not exist
// after
mkdir -p /var/log/bd && export BEADS_PROXIED_SERVER_LOG=/var/log/bd/server.log
Defensive patterns

Strategy: validation

Validate before calling

logPath := os.Getenv("BEADS_PROXIED_SERVER_LOG")
if logPath != "" {
	parent := filepath.Dir(logPath)
	if fi, err := os.Stat(parent); err != nil || !fi.IsDir() {
		return fmt.Errorf("log parent %s missing or not a directory", parent)
	}
	if fi, err := os.Stat(logPath); err == nil && !fi.Mode().IsRegular() {
		return fmt.Errorf("log %s is not a regular file", logPath)
	}
}

Prevention

When it happens

Trigger: BEADS_PROXIED_SERVER_LOG or sidecar log_path points into a nonexistent or non-directory parent (e.g. /var/log/bd missing); the log path exists but is a directory, FIFO, or device; stat on the log or its parent fails for reasons other than NotExist (e.g. EACCES).

Common situations: User set BEADS_PROXIED_SERVER_LOG to a path whose parent was never created; a log rotation tool replaced server.log with a directory; the sidecar log_path points at a mount point or socket.

Related errors


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