gastownhall/beads · error
parsing %s: %w
Error message
parsing %s: %w
What it means
LoadProxiedServerClientInfo read the file successfully but json.Unmarshal could not parse its contents as ProxiedServerClientInfo, and wraps the JSON error. This means the file exists and is readable but is corrupt, truncated, empty, or was written in a different format than the current struct expects.
Source
Thrown at internal/configfile/proxied_server_client_info.go:37
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 {
return fmt.Errorf("writing %s: %w", ProxiedServerClientInfoFileName, err)
}
return nil
}View on GitHub (pinned to 71377f2769)
Solutions
- Validate the JSON (jq . <file>) to see the exact syntax error at the wrapped offset; fix or restore it.
- Delete the corrupt file and restart/reattach the proxied server so SaveProxiedServerClientInfo regenerates it: rm -f .beads/proxied_server_client_info.json.
- If you hand-edited it, restore valid JSON matching ProxiedServerClientInfo fields (strings for IDs/addresses, etc.).
- Check for a version mismatch — upgrade or downgrade bd so the reader matches the writer's format.
Example fix
// before
{"host": "127.0.0.1", "port": // truncated
// after
# rm -f .beads/proxied_server_client_info.json && bd <start-server-cmd>
{"host": "127.0.0.1", "port": 50051} Defensive patterns
Strategy: try-catch
Validate before calling
path := filepath.Join(beadsDir, configfile.ProxiedServerClientInfoFileName)
if data, err := os.ReadFile(path); err == nil {
var probe map[string]any
if json.Unmarshal(data, &probe) != nil {
os.Remove(path) // let the server regenerate it
}
} Try / catch
info, err := configfile.LoadProxiedServerClientInfo(beadsDir)
if err != nil {
var jsonErr *json.SyntaxError
if errors.As(err, &jsonErr) {
log.Printf("corrupt proxied server info at offset %d: %v — regenerating", jsonErr.Offset, jsonErr)
os.Remove(filepath.Join(beadsDir, configfile.ProxiedServerClientInfoFileName))
}
return err
} Prevention
- Never hand-edit the generated JSON file
- Use atomic writes (temp file + rename) when tooling writes this file
- After crashes or version upgrades, delete and regenerate rather than repair
When it happens
Trigger: Calling LoadProxiedServerClientInfo when the JSON file contains invalid syntax (truncated write, manual edit), is empty (0 bytes), or its fields/types no longer match the ProxiedServerClientInfo struct after a version change.
Common situations: Process killed mid-write leaving a partial file; hand-editing the JSON and breaking syntax; upgrading/downgrading bd so the stored shape changed; file corrupted by disk issues or sync tools (Dropbox etc.).
Related errors
- parsing config: %w
- parsing central config %s: %w
- parsing legacy config: %w
- parse %s: %w
- failed to parse backup state: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/8bb81c9010b66d34.
Report an issue: GitHub.