{"record":{"id":"37cfb4511c48dfbc","repo":"gastownhall/beads","slug":"parsing-config-w","errorCode":null,"errorMessage":"parsing config: %w","messagePattern":"parsing config: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/configfile/configfile.go","lineNumber":119,"sourceCode":"\t\t}\n\n\t\t// Save to new location\n\t\tif err := cfg.Save(beadsDir); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"migrating config to metadata.json: %w\", err)\n\t\t}\n\n\t\t// Remove legacy file (best effort: migration already saved to new location)\n\t\t_ = os.Remove(legacyPath)\n\n\t\treturn &cfg, nil\n\t}\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"reading config: %w\", err)\n\t}\n\n\tvar cfg Config\n\tif err := json.Unmarshal(data, &cfg); err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing config: %w\", err)\n\t}\n\n\treturn &cfg, nil\n}\n\n// LoadForDiscovery reads workspace metadata without migrating or rewriting it.\n//\n// Store admission uses this only to classify a workspace before a command can\n// open storage. In particular, legacy config.json remains in place so a failed\n// admission cannot turn a recoverable old workspace into a partially migrated\n// one. Unknown JSON fields remain tolerated here because callers use the\n// result only to decide whether to issue a conservative refusal; normal store\n// selection keeps its existing validation.\nfunc LoadForDiscovery(beadsDir string) (*Config, error) {\n\tdata, err := os.ReadFile(ConfigPath(beadsDir)) // #nosec G304 -- beadsDir is caller-selected workspace state\n\tif os.IsNotExist(err) {\n\t\tdata, err = os.ReadFile(filepath.Join(beadsDir, \"config.json\")) // #nosec G304 -- legacy workspace state\n\t\tif os.IsNotExist(err) {","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/configfile/configfile.go#L101-L137","documentation":"Load() successfully read .beads/metadata.json but json.Unmarshal failed to decode it into the Config struct. This means the file is corrupt JSON or contains a field with the wrong JSON type (unknown string fields are tolerated, but type mismatches are not). Load fails closed to avoid feeding store selection a broken config.","triggerScenarios":"Calling configfile.Load(beadsDir) when metadata.json is truncated/torn (e.g. written by an older bd that used plain os.WriteFile), hand-edited with syntax errors, or has type mismatches like \"dolt_server_port\": \"3307\" (string instead of int).","commonSituations":"Workspaces touched by concurrent bd versions (pre-atomic-write builds); manual edits adding trailing commas; scripts rewriting metadata.json with wrong types; git merge conflicts leaving conflict markers in the file.","solutions":["Validate the file: jq . .beads/metadata.json and fix reported syntax errors","Fix field types against the Config struct (ports and day counts must be numbers, not strings)","Restore from backup or git; or remove metadata.json and re-run bd init (legacy config.json migration will re-run if present)","Prefer LoadForDiscovery only for classification; for a broken file do not hand-write JSON — let bd regenerate it"],"exampleFix":"// before\n{ \"dolt_server_port\": \"3307\", }\n// after\n{ \"dolt_server_port\": 3307 }","handlingStrategy":"validation","validationCode":"data, err := os.ReadFile(filepath.Join(beadsDir, \"metadata.json\"))\nif err == nil {\n\tvar probe map[string]any\n\tif jerr := json.Unmarshal(data, &probe); jerr != nil {\n\t\treturn fmt.Errorf(\"metadata.json corrupt, restore or re-init: %w\", jerr)\n\t}\n}","typeGuard":"func validConfigFile(path string) bool {\n\tdata, err := os.ReadFile(path)\n\tif err != nil { return false }\n\tvar v map[string]any\n\treturn json.Unmarshal(data, &v) == nil\n}","tryCatchPattern":"cfg, err := configfile.Load(beadsDir)\nif err != nil {\n\tvar typeErr *json.UnmarshalTypeError\n\tif errors.As(err, &typeErr) {\n\t\treturn fmt.Errorf(\"field %s has wrong JSON type at offset %d\", typeErr.Field, typeErr.Offset)\n\t}\n\treturn err\n}","preventionTips":["Keep bd versions consistent across machines sharing a workspace","Never edit metadata.json manually; use bd commands","Rely on bd's atomic write — avoid scripts that os.WriteFile metadata.json directly","Resolve git conflicts by regenerating metadata.json, not merging markers"],"tags":["json","config","parsing","corruption"],"backgroundTag":"invalid-config-json","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}