gastownhall/beads · error

reading central config: %w

Error message

reading central config: %w

What it means

LoadCentralConfig wraps any non-ENOENT error from os.ReadFile of the central (shared) config file with "reading central config: %w". A missing file returns nil,nil, so this error means the file exists but could not be read (permissions, I/O, path issues).

Source

Thrown at internal/configfile/central_config.go:42

		}
	}
	home, err := os.UserHomeDir()
	if err != nil {
		return ""
	}
	return filepath.Join(home, ".config", "beads", CentralConfigFileName)
}

// LoadCentralConfig reads the central server config from the given path.
// Returns (nil, nil) if the file does not exist (graceful skip).
// Returns an error only if the file exists but cannot be parsed.
func LoadCentralConfig(path string) (*Config, error) {
	data, err := os.ReadFile(path) // #nosec G304 - path from DefaultCentralConfigPath or env
	if os.IsNotExist(err) {
		return nil, nil
	}
	if err != nil {
		return nil, fmt.Errorf("reading central config: %w", err)
	}

	var cfg Config
	if err := json.Unmarshal(data, &cfg); err != nil {
		return nil, fmt.Errorf("parsing central config %s: %w", path, err)
	}
	return &cfg, nil
}

// ApplyCentralDefaults merges server-related fields from the central config
// into the per-project config, but only for fields that are at their zero
// value in the project config. Non-server fields (Database, DoltDatabase,
// DoltDataDir, ProjectID, etc.) are never inherited from the central config
// because they are inherently per-project.
//
// This is a no-op if central is nil.
func ApplyCentralDefaults(project *Config, central *Config) {
	if central == nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check file permissions: `ls -l <path>` and add read permission (`chmod +r`)
  2. Verify the path env override points at the JSON file, not a directory
  3. If on a network mount, verify the mount is healthy or copy the config locally

Example fix

// before
BD_CENTRAL_CONFIG=/etc/bd/central.d LoadCentralConfig(path)
// after
BD_CENTRAL_CONFIG=/etc/bd/central.json LoadCentralConfig(path)
Defensive patterns

Strategy: try-catch

Validate before calling

fi, err := os.Stat(path)
if err != nil { /* path bad */ } else if fi.IsDir() { /* env var points at a directory */ } else if fi.Mode().Perm()&0o444 == 0 { /* unreadable */ }

Try / catch

cfg, err := bd.LoadCentralConfig(path)
if err != nil {
    if errors.Is(err, fs.ErrPermission) { /* chmod +r or run as owner */ }
    // non-nil cfg is guaranteed unmodified; fail safe
    return err
}

Prevention

When it happens

Trigger: LoadCentralConfig(path) when the central config exists but os.ReadFile fails with e.g. EACCES, EISDIR, or a device error — path comes from DefaultCentralConfigPath or an env override.

Common situations: Central config in a shared/team location owned by another user or read-protected; path env var pointing at a directory; NFS/network mount failures.

Related errors


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