gastownhall/beads · error

ensureProxiedServerConfig: custom config %s: not a regular f

Error message

ensureProxiedServerConfig: custom config %s: not a regular file

What it means

ensureProxiedServerConfig validates a user-supplied (custom) server config path before the proxied daemon uses it. After os.Stat succeeds, it checks that the path is a regular file; directories, sockets, FIFOs, and device nodes are rejected because the config must be readable YAML at a plain file path. This guards the proxy against silently treating a directory or special file as its configuration.

Source

Thrown at cmd/bd/proxied_server.go:131

	if err := validateProxiedServerConfig(path); err != nil {
		return "", fmt.Errorf("ensureProxiedServerConfig: %w", err)
	}
	return path, nil
}

func resolveOrCreateProxiedServerConfig(beadsDir string) (string, error) {
	path, isCustom, err := resolveProxiedServerConfigPath(beadsDir)
	if err != nil {
		return "", err
	}

	if isCustom {
		info, err := os.Stat(path)
		if err != nil {
			return "", fmt.Errorf("ensureProxiedServerConfig: custom config %s: %w", path, err)
		}
		if !info.Mode().IsRegular() {
			return "", fmt.Errorf("ensureProxiedServerConfig: custom config %s: not a regular file", path)
		}
		return path, nil
	}

	root := filepath.Dir(path)
	if err := os.MkdirAll(root, config.BeadsDirPerm); err != nil {
		return "", fmt.Errorf("ensureProxiedServerConfig: mkdir %s: %w", root, err)
	}

	switch _, err := os.Stat(path); {
	case err == nil:
		return path, nil
	case !os.IsNotExist(err):
		return "", fmt.Errorf("ensureProxiedServerConfig: stat %s: %w", path, err)
	}

	port, err := proxy.PickFreePort()
	if err != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify the path is the intended YAML config file, not a directory or special file: run `ls -la <path>` and confirm it is a regular file (`-` in the first column of ls output).
  2. If the file does not exist yet, create it as a regular file (e.g. `touch ~/.beads/proxied-server.yaml`) or let bd generate a default config by not passing a custom path.
  3. Remove a mistakenly created directory/socket at that path (`rm -rf <path>` if it is a directory you made in error) and recreate as a file.
  4. If the path intentionally points elsewhere, pass the correct file path to the bd command or fix the environment variable / config source supplying it.

Example fix

// before
$ bd serve --config ~/.beads/            # directory, not a file
// after
$ bd serve --config ~/.beads/proxied-server.yaml
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(cfgPath)
if err != nil {
	return fmt.Errorf("config path %s: %w", cfgPath, err)
}
if !info.Mode().IsRegular() {
	return fmt.Errorf("config path %s is not a regular file", cfgPath)
}

Type guard

func isRegularFile(path string) bool {
	info, err := os.Stat(path)
	return err == nil && info.Mode().IsRegular()
}

Prevention

When it happens

Trigger: Running `bd` with a custom proxied-server config path (--config or env-provided) that points at a directory, a Unix socket, /dev/null, a named pipe, or any non-regular filesystem entry.

Common situations: Passing a directory instead of a file (e.g. `~/.beads` instead of `~/.beads/proxied-server.yaml`); pointing the config at a socket path used by another tool; copy-pasting a path with a trailing slash; using /dev/null to 'disable' config.

Related errors


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