gastownhall/beads · error
reading %s: %w
Error message
reading %s: %w
What it means
LoadProxiedServerClientInfo failed to read the proxied server client info JSON file and wraps the os.ReadFile error. A missing file is treated as "no info" (returns nil, nil), so this error means the file exists but could not be read — permissions, I/O error, or it is a directory. It surfaces when the tool tries to load connection info for a proxied Dolt server.
Source
Thrown at internal/configfile/proxied_server_client_info.go:33
ConfigPath string `json:"config_path,omitempty"`
LogPath string `json:"log_path,omitempty"`
Port int `json:"port,omitempty"`
IdleTimeout time.Duration `json:"idle_timeout,omitempty"`
External *ExternalDoltConfig `json:"external,omitempty"`
}
func ProxiedServerClientInfoPath(beadsDir string) string {
return filepath.Join(beadsDir, ProxiedServerClientInfoFileName)
}
func LoadProxiedServerClientInfo(beadsDir string) (*ProxiedServerClientInfo, error) {
path := ProxiedServerClientInfoPath(beadsDir)
data, err := os.ReadFile(path) // #nosec G304 - controlled path
if os.IsNotExist(err) {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("reading %s: %w", ProxiedServerClientInfoFileName, err)
}
var info ProxiedServerClientInfo
if err := json.Unmarshal(data, &info); err != nil {
return nil, fmt.Errorf("parsing %s: %w", ProxiedServerClientInfoFileName, err)
}
return &info, nil
}
func SaveProxiedServerClientInfo(beadsDir string, info *ProxiedServerClientInfo) error {
if info == nil {
info = &ProxiedServerClientInfo{}
}
data, err := json.MarshalIndent(info, "", " ")
if err != nil {
return fmt.Errorf("marshaling %s: %w", ProxiedServerClientInfoFileName, err)
}
path := ProxiedServerClientInfoPath(beadsDir)
if err := os.WriteFile(path, data, 0o600); err != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Check ownership/permissions: ls -l .beads/proxied_server_client_info.json; chown/chmod so the current user can read it, or delete it and let the server re-create it.
- If the path is a directory, remove it and restart the proxied server to regenerate the file.
- Re-run the command that starts/registers the proxied server so SaveProxiedServerClientInfo rewrites the file.
- Inspect the wrapped %w error for the exact OS reason (EACCES, EISDIR, EIO) and address accordingly.
Example fix
// before # ls -l .beads/proxied_server_client_info.json -> owned by root // after # sudo chown $USER .beads/proxied_server_client_info.json
Defensive patterns
Strategy: try-catch
Validate before calling
info, err := configfile.LoadProxiedServerClientInfo(beadsDir)
if err != nil {
if perr, ok := err.(*fs.PathError); ok && perr.Err == syscall.EACCES {
log.Fatalf("cannot read proxied server info (permissions): %v", perr)
}
return err
} Try / catch
info, err := configfile.LoadProxiedServerClientInfo(beadsDir)
if err != nil {
var perr *fs.PathError
if errors.As(err, &perr) {
log.Printf("proxied server info unreadable (%v); attempting regeneration", perr.Err)
os.Remove(filepath.Join(beadsDir, configfile.ProxiedServerClientInfoFileName))
}
return err
} Prevention
- Run all bd commands as the same user to avoid ownership mismatches
- Do not replace the info file with a directory or symlink
- Treat the file as machine-generated: never hand-edit or version-control it
When it happens
Trigger: Calling LoadProxiedServerClientInfo when ProxiedServerClientInfoFileName inside the beads dir exists but is unreadable by the current user, is a directory, or the filesystem returns an I/O error.
Common situations: File created by a different user (e.g. root ran bd once, then a normal user); stale file replaced by a directory; NFS/network filesystem hiccup; restrictive umask or sandboxed environment blocking read.
Related errors
- failed to read config.yaml: %w
- reading config: %w
- failed to read backup state: %w
- failed to write temp file: %w
- failed to sync temp file: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/7612e1eef84f3a1e.
Report an issue: GitHub.